Commit 03dc00fe authored by 王宇航's avatar 王宇航

lab3本地测试

parent d298bd3e
......@@ -39,6 +39,7 @@ INCLUDE_DIRECTORIES(
include/cminusfc
include/common
include/lightir
include/codegen
${LLVM_INCLUDE_DIRS}
)
......
# 简介
本仓库为 USTC 编译原理和技术 2025 的课程实验仓库。在本学期的编译实验中,你们将构建一个从词法分析器开始到后端代码生成的JIANMU编译器。
本仓库为 USTC 编译原理和技术 2024 的课程实验仓库。在本学期的编译实验中,你们将构建一个从词法分析器开始到后端代码生成的JIANMU编译器。
你们需要 fork 此 repo 到自己的仓库下,随后在自己的仓库中完成实验。
## 测试脚本使用方法
eval_lab2.sh:
没有参数,直接运行即可,结果会生成在 eval_result 下
\ No newline at end of file
File mode changed from 100644 to 100755
#pragma once
#include <cassert>
#include <string>
struct ASMInstruction {
enum InstType { Instruction, Atrribute, Label, Comment } type;
std::string content;
explicit ASMInstruction(std::string s, InstType ty = Instruction)
: type(ty), content(s) {}
std::string format() const {
switch (type) {
case ASMInstruction::Instruction:
case ASMInstruction::Atrribute:
return "\t" + content + "\n";
case ASMInstruction::Label:
return content + ":\n";
case ASMInstruction::Comment:
return "# " + content + "\n";
}
assert(false && "unreachable");
}
};
#pragma once
#include "ASMInstruction.hpp"
#include "Module.hpp"
#include "Register.hpp"
class CodeGen {
public:
explicit CodeGen(Module *module) : m(module) {}
std::string print() const;
void run();
template <class... Args> void append_inst(Args... arg) {
output.emplace_back(arg...);
}
void
append_inst(const char *inst, std::initializer_list<std::string> args,
ASMInstruction::InstType ty = ASMInstruction::Instruction) {
auto content = std::string(inst) + " ";
for (const auto &arg : args) {
content += arg + ", ";
}
content.pop_back();
content.pop_back();
output.emplace_back(content, ty);
}
private:
void allocate();
void copy_stmt(); // for phi copy
// 向寄存器中装载数据
void load_to_greg(Value *, const Reg &);
void load_to_freg(Value *, const FReg &);
void load_from_stack_to_greg(Value *, const Reg &);
// 向寄存器中加载立即数
void load_large_int32(int32_t, const Reg &);
void load_large_int64(int64_t, const Reg &);
void load_float_imm(float, const FReg &);
// 将寄存器中的数据保存回栈上
void store_from_greg(Value *, const Reg &);
void store_from_freg(Value *, const FReg &);
void gen_prologue();
void gen_ret();
void gen_br();
void gen_binary();
void gen_float_binary();
void gen_alloca();
void gen_load();
void gen_store();
void gen_icmp();
void gen_fcmp();
void gen_zext();
void gen_call();
void gen_gep();
void gen_sitofp();
void gen_fptosi();
void gen_epilogue();
static std::string label_name(BasicBlock *bb) {
return "." + bb->get_parent()->get_name() + "_" + bb->get_name();
}
static std::string func_exit_label_name(Function *func) {
return func->get_name() + "_exit";
}
static std::string fcmp_label_name(BasicBlock *bb, unsigned cnt) {
return label_name(bb) + "_fcmp_" + std::to_string(cnt);
}
struct {
/* 随着ir遍历设置 */
Function *func{nullptr}; // 当前函数
BasicBlock *bb{nullptr}; // 当前基本块
Instruction *inst{nullptr}; // 当前指令
/* 在allocate()中设置 */
unsigned frame_size{0}; // 当前函数的栈帧大小
std::unordered_map<Value *, int> offset_map{}; // 指针相对 fp 的偏移
unsigned fcmp_cnt{0}; // fcmp 的计数器, 用于创建 fcmp 需要的 label
void clear() {
func = nullptr;
bb = nullptr;
inst = nullptr;
frame_size = 0;
fcmp_cnt = 0;
offset_map.clear();
}
} context;
Module *m;
std::list<ASMInstruction> output;
};
#pragma once
#include <stdexcept>
/* 关于位宽 */
#define IMM_12_MAX 0x7FF
#define IMM_12_MIN -0x800
#define LOW_12_MASK 0x00000FFF
#define LOW_20_MASK 0x000FFFFF
#define LOW_32_MASK 0xFFFFFFFF
inline unsigned ALIGN(unsigned x, unsigned alignment) {
return ((x + (alignment - 1)) & ~(alignment - 1));
}
inline bool IS_IMM_12(int x) { return x <= IMM_12_MAX and x >= IMM_12_MIN; }
/* 栈帧相关 */
#define PROLOGUE_OFFSET_BASE 16 // $ra $fp
#define PROLOGUE_ALIGN 16
/* 龙芯指令 */
// Arithmetic
#define ADD "add"
#define SUB "sub"
#define MUL "mul"
#define DIV "div"
#define ADDI "addi"
#define FADD "fadd"
#define FSUB "fsub"
#define FMUL "fmul"
#define FDIV "fdiv"
#define ORI "ori"
#define LU12I_W "lu12i.w"
#define LU32I_D "lu32i.d"
#define LU52I_D "lu52i.d"
// Data transfer (greg <-> freg)
#define GR2FR "movgr2fr"
#define FR2GR "movfr2gr"
// Memory access
#define LOAD "ld"
#define STORE "st"
#define FLOAD "fld"
#define FSTORE "fst"
#define BYTE ".b"
#define HALF_WORD ".h"
#define WORD ".w"
#define DOUBLE ".d"
#define SINGLE ".s" // float
#define LONG ".l"
// ASM syntax sugar
#define LOAD_ADDR "la.local"
// errors
class not_implemented_error : public std::logic_error {
public:
explicit not_implemented_error(std::string &&err_msg = "")
: std::logic_error(err_msg){};
};
class unreachable_error : public std::logic_error {
public:
explicit unreachable_error(std::string &&err_msg = "")
: std::logic_error(err_msg){};
};
#pragma once
#include <cassert>
#include <string>
/* General-purpose Register Convention:
* Name Alias Meaning
* $r0 $zero constant 0
* $r1 $ra return address
* $r2 $tp thread pointer
* $r3 $sp stack pointer
* $r4 - $r5 $a0 - $a1 argument, return value
* $r6 - $r11 $a2 - $a7 argument
* $r12 - $r20 $t0 - $t8 temporary
* $r21 saved
* $r22 $fp / $s9 frame pointer
* $r23 - $r31 $s0 - $s8 static
*
* Floating-point Register Convention
* Name Alias Meaning
* $f0-$f1 $fa0-$fa1 argument/return value
* $f2-$f7 $fa2-$fa7 argument
* $f8-$f23 $ft0-$ft15 temporary
* $f24-$f31 $fs0-$fs7 static
*/
struct Reg {
unsigned id;
explicit Reg(unsigned i) : id(i) { assert(i <= 31); }
bool operator==(const Reg &other) { return id == other.id; }
std::string print() const;
static Reg zero() { return Reg(0); }
static Reg ra() { return Reg(1); }
static Reg sp() { return Reg(3); }
static Reg fp() { return Reg(22); }
static Reg a(unsigned i) {
assert(0 <= i and i <= 7);
return Reg(i + 4);
}
static Reg t(unsigned i) {
assert(0 <= i and i <= 8);
return Reg(i + 12);
}
static Reg s(unsigned i) {
assert(0 <= i and i <= 9);
if (i == 9)
return Reg(22);
else
return Reg(i + 23);
}
};
struct FReg {
unsigned id;
explicit FReg(unsigned i) : id(i) { assert(i <= 31); }
bool operator==(const FReg &other) { return id == other.id; }
std::string print() const;
static FReg fa(unsigned i) {
assert(0 <= i and i <= 7);
return FReg(i);
}
static FReg ft(unsigned i) {
assert(0 <= i and i <= 15);
return FReg(i + 8);
}
static FReg fs(unsigned i) {
assert(0 <= i and i <= 7);
return FReg(i + 24);
}
};
struct CFReg {
unsigned id;
explicit CFReg(unsigned i) : id(i) { assert(i <= 7); }
bool operator==(const CFReg &other) { return id == other.id; }
std::string print() const { return "$fcc" + std::to_string(id); }
};
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -3,4 +3,5 @@ add_subdirectory(common)
add_subdirectory(logging)
add_subdirectory(cminusfc)
add_subdirectory(lightir)
add_subdirectory(io)
\ No newline at end of file
add_subdirectory(io)
add_subdirectory(codegen)
\ No newline at end of file
......@@ -8,6 +8,7 @@ target_link_libraries(
cminusfc
IR_lib
common
codegen
syntax
stdc++fs
)
......
File mode changed from 100644 to 100755
#include "Module.hpp"
#include "ast.hpp"
#include "cminusf_builder.hpp"
#include "CodeGen.hpp"
#include <filesystem>
#include <fstream>
......@@ -16,6 +17,7 @@ struct Config {
std::filesystem::path output_file;
bool emitast{false};
bool emitasm{false};
bool emitllvm{false};
Config(int argc, char **argv) : argc(argc), argv(argv) {
......@@ -55,9 +57,13 @@ int main(int argc, char **argv) {
output_stream << "; ModuleID = 'cminus'\n";
output_stream << "source_filename = " << abs_path << "\n\n";
output_stream << m->print();
} else if (config.emitasm) {
CodeGen codegen(m.get());
codegen.run();
output_stream << codegen.print();
}
// TODO: lab3 lab4 (IR optimization or codegen)
// TODO: lab4 (IR optimization or codegen)
}
return 0;
......@@ -77,6 +83,8 @@ void Config::parse_cmd_line() {
}
} else if (argv[i] == "-emit-ast"s) {
emitast = true;
} else if (argv[i] == "-S"s) {
emitasm = true;
} else if (argv[i] == "-emit-llvm"s) {
emitllvm = true;
} else {
......@@ -95,11 +103,9 @@ void Config::check() {
if (input_file.empty()) {
print_err("no input file");
}
/*
if (input_file.extension() != ".cminus") {
print_err("file format not recognized");
}
*/
if (output_file.empty()) {
output_file = input_file.stem();
}
......@@ -107,7 +113,7 @@ void Config::check() {
void Config::print_help() const {
std::cout << "Usage: " << exe_name
<< " [-h|--help] [-o <target-file>] [-mem2reg] [-emit-llvm] [-S] "
<< " [-h|--help] [-o <target-file>] [-emit-ast] [-emit-llvm] [-S] "
"<input-file>"
<< std::endl;
exit(0);
......
add_library(
codegen STATIC
CodeGen.cpp
Register.cpp
)
target_link_libraries(codegen common IR_lib)
#include "CodeGen.hpp"
#include "CodeGenUtil.hpp"
void CodeGen::allocate() {
// 备份 $ra $fp
unsigned offset = PROLOGUE_OFFSET_BASE;
// 为每个参数分配栈空间
for (auto &arg : context.func->get_args()) {
auto size = arg.get_type()->get_size();
offset = offset + size;
context.offset_map[&arg] = -static_cast<int>(offset);
}
// 为指令结果分配栈空间
for (auto &bb : context.func->get_basic_blocks()) {
for (auto &instr : bb.get_instructions()) {
// 每个非 void 的定值都分配栈空间
if (not instr.is_void()) {
auto size = instr.get_type()->get_size();
offset = offset + size;
context.offset_map[&instr] = -static_cast<int>(offset);
}
// alloca 的副作用:分配额外空间
if (instr.is_alloca()) {
auto *alloca_inst = static_cast<AllocaInst *>(&instr);
auto alloc_size = alloca_inst->get_alloca_type()->get_size();
offset += alloc_size;
}
}
}
// 分配栈空间,需要是 16 的整数倍
context.frame_size = ALIGN(offset, PROLOGUE_ALIGN);
}
void CodeGen::copy_stmt() {
for (auto &succ : context.bb->get_succ_basic_blocks()) {
for (auto &inst : succ->get_instructions()) {
if (inst.is_phi()) {
// 遍历后继块中 phi 的定值 bb
for (unsigned i = 1; i < inst.get_operands().size(); i += 2) {
// phi 的定值 bb 是当前翻译块
if (inst.get_operand(i) == context.bb) {
auto *lvalue = inst.get_operand(i - 1);
if (lvalue->get_type()->is_float_type()) {
load_to_freg(lvalue, FReg::fa(0));
store_from_freg(&inst, FReg::fa(0));
} else {
load_to_greg(lvalue, Reg::a(0));
store_from_greg(&inst, Reg::a(0));
}
break;
}
// 如果没有找到当前翻译块,说明是 undef,无事可做
}
} else {
break;
}
}
}
}
void CodeGen::load_to_greg(Value *val, const Reg &reg) {
assert(val->get_type()->is_integer_type() ||
val->get_type()->is_pointer_type());
if (auto *constant = dynamic_cast<ConstantInt *>(val)) {
int32_t val = constant->get_value();
if (IS_IMM_12(val)) {
append_inst(ADDI WORD, {reg.print(), "$zero", std::to_string(val)});
} else {
load_large_int32(val, reg);
}
} else if (auto *global = dynamic_cast<GlobalVariable *>(val)) {
append_inst(LOAD_ADDR, {reg.print(), global->get_name()});
} else {
load_from_stack_to_greg(val, reg);
}
}
void CodeGen::load_large_int32(int32_t val, const Reg &reg) {
int32_t high_20 = val >> 12; // si20
uint32_t low_12 = val & LOW_12_MASK;
append_inst(LU12I_W, {reg.print(), std::to_string(high_20)});
append_inst(ORI, {reg.print(), reg.print(), std::to_string(low_12)});
}
void CodeGen::load_large_int64(int64_t val, const Reg &reg) {
auto low_32 = static_cast<int32_t>(val & LOW_32_MASK);
load_large_int32(low_32, reg);
auto high_32 = static_cast<int32_t>(val >> 32);
int32_t high_32_low_20 = (high_32 << 12) >> 12; // si20
int32_t high_32_high_12 = high_32 >> 20; // si12
append_inst(LU32I_D, {reg.print(), std::to_string(high_32_low_20)});
append_inst(LU52I_D,
{reg.print(), reg.print(), std::to_string(high_32_high_12)});
}
void CodeGen::load_from_stack_to_greg(Value *val, const Reg &reg) {
auto offset = context.offset_map.at(val);
auto offset_str = std::to_string(offset);
auto *type = val->get_type();
if (IS_IMM_12(offset)) {
if (type->is_int1_type()) {
append_inst(LOAD BYTE, {reg.print(), "$fp", offset_str});
} else if (type->is_int32_type()) {
append_inst(LOAD WORD, {reg.print(), "$fp", offset_str});
} else { // Pointer
append_inst(LOAD DOUBLE, {reg.print(), "$fp", offset_str});
}
} else {
load_large_int64(offset, reg);
append_inst(ADD DOUBLE, {reg.print(), "$fp", reg.print()});
if (type->is_int1_type()) {
append_inst(LOAD BYTE, {reg.print(), reg.print(), "0"});
} else if (type->is_int32_type()) {
append_inst(LOAD WORD, {reg.print(), reg.print(), "0"});
} else { // Pointer
append_inst(LOAD DOUBLE, {reg.print(), reg.print(), "0"});
}
}
}
void CodeGen::store_from_greg(Value *val, const Reg &reg) {
auto offset = context.offset_map.at(val);
auto offset_str = std::to_string(offset);
auto *type = val->get_type();
if (IS_IMM_12(offset)) {
if (type->is_int1_type()) {
append_inst(STORE BYTE, {reg.print(), "$fp", offset_str});
} else if (type->is_int32_type()) {
append_inst(STORE WORD, {reg.print(), "$fp", offset_str});
} else { // Pointer
append_inst(STORE DOUBLE, {reg.print(), "$fp", offset_str});
}
} else {
auto addr = Reg::t(8);
load_large_int64(offset, addr);
append_inst(ADD DOUBLE, {addr.print(), "$fp", addr.print()});
if (type->is_int1_type()) {
append_inst(STORE BYTE, {reg.print(), addr.print(), "0"});
} else if (type->is_int32_type()) {
append_inst(STORE WORD, {reg.print(), addr.print(), "0"});
} else { // Pointer
append_inst(STORE DOUBLE, {reg.print(), addr.print(), "0"});
}
}
}
void CodeGen::load_to_freg(Value *val, const FReg &freg) {
assert(val->get_type()->is_float_type());
if (auto *constant = dynamic_cast<ConstantFP *>(val)) {
float val = constant->get_value();
load_float_imm(val, freg);
} else {
auto offset = context.offset_map.at(val);
auto offset_str = std::to_string(offset);
if (IS_IMM_12(offset)) {
append_inst(FLOAD SINGLE, {freg.print(), "$fp", offset_str});
} else {
auto addr = Reg::t(8);
load_large_int64(offset, addr);
append_inst(ADD DOUBLE, {addr.print(), "$fp", addr.print()});
append_inst(FLOAD SINGLE, {freg.print(), addr.print(), "0"});
}
}
}
void CodeGen::load_float_imm(float val, const FReg &r) {
int32_t bytes = *reinterpret_cast<int32_t *>(&val);
load_large_int32(bytes, Reg::t(8));
append_inst(GR2FR WORD, {r.print(), Reg::t(8).print()});
}
void CodeGen::store_from_freg(Value *val, const FReg &r) {
auto offset = context.offset_map.at(val);
if (IS_IMM_12(offset)) {
auto offset_str = std::to_string(offset);
append_inst(FSTORE SINGLE, {r.print(), "$fp", offset_str});
} else {
auto addr = Reg::t(8);
load_large_int64(offset, addr);
append_inst(ADD DOUBLE, {addr.print(), "$fp", addr.print()});
append_inst(FSTORE SINGLE, {r.print(), addr.print(), "0"});
}
}
void CodeGen::gen_prologue() {
if (IS_IMM_12(-static_cast<int>(context.frame_size))) {
append_inst("st.d $ra, $sp, -8");
append_inst("st.d $fp, $sp, -16");
append_inst("addi.d $fp, $sp, 0");
append_inst("addi.d $sp, $sp, " +
std::to_string(-static_cast<int>(context.frame_size)));
} else {
load_large_int64(context.frame_size, Reg::t(0));
append_inst("st.d $ra, $sp, -8");
append_inst("st.d $fp, $sp, -16");
append_inst("sub.d $sp, $sp, $t0");
append_inst("add.d $fp, $sp, $t0");
}
int garg_cnt = 0;
int farg_cnt = 0;
for (auto &arg : context.func->get_args()) {
if (arg.get_type()->is_float_type()) {
store_from_freg(&arg, FReg::fa(farg_cnt++));
} else { // int or pointer
store_from_greg(&arg, Reg::a(garg_cnt++));
}
}
}
void CodeGen::gen_epilogue() {
// TODO 根据你的理解设定函数的 epilogue
throw not_implemented_error{__FUNCTION__};
}
void CodeGen::gen_ret() {
// TODO 函数返回,思考如何处理返回值、寄存器备份,如何返回调用者地址
throw not_implemented_error{__FUNCTION__};
}
void CodeGen::gen_br() {
auto *branchInst = static_cast<BranchInst *>(context.inst);
if (branchInst->is_cond_br()) {
// TODO 补全条件跳转的情况
throw not_implemented_error{__FUNCTION__};
} else {
auto *branchbb = static_cast<BasicBlock *>(branchInst->get_operand(0));
append_inst("b " + label_name(branchbb));
}
}
void CodeGen::gen_binary() {
load_to_greg(context.inst->get_operand(0), Reg::t(0));
load_to_greg(context.inst->get_operand(1), Reg::t(1));
switch (context.inst->get_instr_type()) {
case Instruction::add:
output.emplace_back("add.w $t2, $t0, $t1");
break;
case Instruction::sub:
output.emplace_back("sub.w $t2, $t0, $t1");
break;
case Instruction::mul:
output.emplace_back("mul.w $t2, $t0, $t1");
break;
case Instruction::sdiv:
output.emplace_back("div.w $t2, $t0, $t1");
break;
default:
assert(false);
}
store_from_greg(context.inst, Reg::t(2));
}
void CodeGen::gen_float_binary() {
// TODO 浮点类型的二元指令
throw not_implemented_error{__FUNCTION__};
}
void CodeGen::gen_alloca() {
/* 我们已经为 alloca 的内容分配空间,在此我们还需保存 alloca
* 指令自身产生的定值,即指向 alloca 空间起始地址的指针
*/
// TODO 将 alloca 出空间的起始地址保存在栈帧上
throw not_implemented_error{__FUNCTION__};
}
void CodeGen::gen_load() {
auto *ptr = context.inst->get_operand(0);
auto *type = context.inst->get_type();
load_to_greg(ptr, Reg::t(0));
if (type->is_float_type()) {
append_inst("fld.s $ft0, $t0, 0");
store_from_freg(context.inst, FReg::ft(0));
} else {
// TODO load 整数类型的数据
throw not_implemented_error{__FUNCTION__};
}
}
void CodeGen::gen_store() {
// TODO 翻译 store 指令
throw not_implemented_error{__FUNCTION__};
}
void CodeGen::gen_icmp() {
// TODO 处理各种整数比较的情况
throw not_implemented_error{__FUNCTION__};
}
void CodeGen::gen_fcmp() {
// TODO 处理各种浮点数比较的情况
throw not_implemented_error{__FUNCTION__};
}
void CodeGen::gen_zext() {
// TODO 将窄位宽的整数数据进行零扩展
throw not_implemented_error{__FUNCTION__};
}
void CodeGen::gen_call() {
// TODO 函数调用,注意我们只需要通过寄存器传递参数,即不需考虑栈上传参的情况
throw not_implemented_error{__FUNCTION__};
}
/*
* %op = getelementptr [10 x i32], [10 x i32]* %op, i32 0, i32 %op
* %op = getelementptr i32, i32* %op, i32 %op
*
* Memory layout
* - ^
* +-----------+ | Smaller address
* | arg ptr |---+ |
* +-----------+ | |
* | | | |
* +-----------+ / |
* | |<-- |
* | | \ |
* | | | |
* | Array | | |
* | | | |
* | | | |
* | | | |
* +-----------+ | |
* | Pointer |---+ |
* +-----------+ |
* | | |
* +-----------+ |
* | | |
* +-----------+ |
* | | |
* +-----------+ | Larger address
* +
*/
void CodeGen::gen_gep() {
// TODO 计算内存地址
throw not_implemented_error{__FUNCTION__};
}
void CodeGen::gen_sitofp() {
// TODO 整数转向浮点数
throw not_implemented_error{__FUNCTION__};
}
void CodeGen::gen_fptosi() {
// TODO 浮点数转向整数,注意向下取整(round to zero)
throw not_implemented_error{__FUNCTION__};
}
void CodeGen::run() {
// 确保每个函数中基本块的名字都被设置好
m->set_print_name();
/* 使用 GNU 伪指令为全局变量分配空间
* 你可以使用 `la.local` 指令将标签 (全局变量) 的地址载入寄存器中, 比如
* 要将 `a` 的地址载入 $t0, 只需要 `la.local $t0, a`
*/
if (!m->get_global_variable().empty()) {
append_inst("Global variables", ASMInstruction::Comment);
/* 虽然下面两条伪指令可以简化为一条 `.bss` 伪指令, 但是我们还是选择使用
* `.section` 将全局变量放到可执行文件的 BSS 段, 原因如下:
* - 尽可能对齐交叉编译器 loongarch64-unknown-linux-gnu-gcc 的行为
* - 支持更旧版本的 GNU 汇编器, 因为 `.bss` 伪指令是应该相对较新的指令,
* GNU 汇编器在 2023 年 2 月的 2.37 版本才将其引入
*/
append_inst(".text", ASMInstruction::Atrribute);
append_inst(".section", {".bss", "\"aw\"", "@nobits"},
ASMInstruction::Atrribute);
for (auto &global : m->get_global_variable()) {
auto size =
global.get_type()->get_pointer_element_type()->get_size();
append_inst(".globl", {global.get_name()},
ASMInstruction::Atrribute);
append_inst(".type", {global.get_name(), "@object"},
ASMInstruction::Atrribute);
append_inst(".size", {global.get_name(), std::to_string(size)},
ASMInstruction::Atrribute);
append_inst(global.get_name(), ASMInstruction::Label);
append_inst(".space", {std::to_string(size)},
ASMInstruction::Atrribute);
}
}
// 函数代码段
output.emplace_back(".text", ASMInstruction::Atrribute);
for (auto &func : m->get_functions()) {
if (not func.is_declaration()) {
// 更新 context
context.clear();
context.func = &func;
// 函数信息
append_inst(".globl", {func.get_name()}, ASMInstruction::Atrribute);
append_inst(".type", {func.get_name(), "@function"},
ASMInstruction::Atrribute);
append_inst(func.get_name(), ASMInstruction::Label);
// 分配函数栈帧
allocate();
// 生成 prologue
gen_prologue();
for (auto &bb : func.get_basic_blocks()) {
context.bb = &bb;
append_inst(label_name(context.bb), ASMInstruction::Label);
for (auto &instr : bb.get_instructions()) {
// For debug
append_inst(instr.print(), ASMInstruction::Comment);
context.inst = &instr; // 更新 context
switch (instr.get_instr_type()) {
case Instruction::ret:
gen_ret();
break;
case Instruction::br:
copy_stmt();
gen_br();
break;
case Instruction::add:
case Instruction::sub:
case Instruction::mul:
case Instruction::sdiv:
gen_binary();
break;
case Instruction::fadd:
case Instruction::fsub:
case Instruction::fmul:
case Instruction::fdiv:
gen_float_binary();
break;
case Instruction::alloca:
/* 对于 alloca 指令,我们已经为 alloca
* 的内容分配空间,在此我们还需保存 alloca
* 指令自身产生的定值,即指向 alloca 空间起始地址的指针
*/
gen_alloca();
break;
case Instruction::load:
gen_load();
break;
case Instruction::store:
gen_store();
break;
case Instruction::ge:
case Instruction::gt:
case Instruction::le:
case Instruction::lt:
case Instruction::eq:
case Instruction::ne:
gen_icmp();
break;
case Instruction::fge:
case Instruction::fgt:
case Instruction::fle:
case Instruction::flt:
case Instruction::feq:
case Instruction::fne:
gen_fcmp();
break;
case Instruction::phi:
/* for phi, just convert to a series of
* copy-stmts */
/* we can collect all phi and deal them at
* the end */
break;
case Instruction::call:
gen_call();
break;
case Instruction::getelementptr:
gen_gep();
break;
case Instruction::zext:
gen_zext();
break;
case Instruction::fptosi:
gen_fptosi();
break;
case Instruction::sitofp:
gen_sitofp();
break;
}
}
}
// 生成 epilogue
gen_epilogue();
}
}
}
std::string CodeGen::print() const {
std::string result;
for (const auto &inst : output) {
result += inst.format();
}
return result;
}
#include "Register.hpp"
#include <string>
std::string Reg::print() const {
if (id == 0) {
return "$zero";
}
if (id == 1) {
return "$ra";
}
if (id == 2) {
return "$tp";
}
if (id == 3) {
return "$sp";
}
if (4 <= id and id <= 11) {
return "$a" + std::to_string(id - 4);
}
if (12 <= id and id <= 20) {
return "$t" + std::to_string(id - 12);
}
if (id == 22) {
return "$fp";
}
assert(false);
}
std::string FReg::print() const {
if (0 <= id and id <= 7) {
return "$fa" + std::to_string(id);
}
if (8 <= id and id <= 23) {
return "$ft" + std::to_string(id - 8);
}
if (24 <= id and id <= 31) {
return "$fs" + std::to_string(id - 24);
}
assert(false);
}
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
#!/bin/bash
rm -rf output log.txt
#!/bin/bash
project_dir=$(realpath ../../../)
io_dir=$(realpath "$project_dir"/src/io)
output_dir=output
suffix=cminus
LOG=log.txt
usage() {
cat <<JIANMU
Usage: $0 [path-to-testcases] [type]
path-to-testcases: './testcases' or '../../testcases_general' or 'self made cases'
type: 'debug' or 'test', debug will output .ll file
JIANMU
exit 0
}
check_return_value() {
rv=$1
expected_rv=$2
fail_msg=$3
detail=$4
if [ "$rv" -eq "$expected_rv" ]; then
return 0
else
printf "\033[1;31m%s: \033[0m%s\n" "$fail_msg" "$detail"
return 1
fi
}
# check arguments
[ $# -lt 2 ] && usage
if [ "$2" == "debug" ]; then
debug_mode=true
elif [ "$2" == "test" ]; then
debug_mode=false
else
usage
fi
test_dir=$1
testcases=$(ls "$test_dir"/*."$suffix" | sort -V)
check_return_value $? 0 "PATH" "unable to access to '$test_dir'" || exit 1
# hide stderr in the script
# exec 2>/dev/null
mkdir -p $output_dir
truncate -s 0 $LOG
if [ $debug_mode = false ]; then
exec 3>/dev/null 4>&1 5>&2 1>&3 2>&3
else
exec 3>&1
fi
if [ $debug_mode = false ]; then
exec 1>&4 2>&5
fi
echo "[info] Start testing, using testcase dir: $test_dir"
# asm
for case in $testcases; do
echo "==========$case==========" >>$LOG
case_base_name=$(basename -s .$suffix "$case")
std_out_file=$test_dir/$case_base_name.out
in_file=$test_dir/$case_base_name.in
asm_file=$output_dir/$case_base_name.s
exe_file=$output_dir/$case_base_name
out_file=$output_dir/$case_base_name.out
ll_file=$output_dir/$case_base_name.ll
echo -n "$case_base_name..."
# if debug mode on, generate .ll also
if [ $debug_mode = true ]; then
bash -c "${project_dir}/build/cminusfc -emit-llvm $case -o $ll_file" >>$LOG 2>&1
fi
# cminusfc compile to .s
bash -c "${project_dir}/build/cminusfc -S $case -o $asm_file" >>$LOG 2>&1
check_return_value $? 0 "CE" "cminusfc compiler error" || continue
# gcc compile asm to executable
loongarch64-unknown-linux-gnu-gcc -static \
"$asm_file" "$io_dir"/io.c -o "$exe_file" \
>>$LOG
check_return_value $? 0 "CE" "gcc compiler error" || continue
# qemu run
if [ -e "$in_file" ]; then
exec_cmd="qemu-loongarch64 $exe_file >$out_file <$in_file"
else
exec_cmd="qemu-loongarch64 $exe_file >$out_file"
fi
bash -c "$exec_cmd"
ret=$?
# remove trailing null byte in the end line
sed -i "\$s/\x00*$//" "$out_file"
# append return value
echo $ret >>"$out_file"
# compare output
diff --strip-trailing-cr "$std_out_file" "$out_file" -y >>$LOG
check_return_value $? 0 "WA" "output differ, check $std_out_file and $out_file" || continue
# ok
printf "\033[1;32mOK\033[0m\n"
done
==========../../testcases_general/1-return.cminus==========
0 0
==========../../testcases_general/2-decl_int.cminus==========
0 0
==========../../testcases_general/3-decl_float.cminus==========
0 0
==========../../testcases_general/4-decl_int_array.cminus==========
0 0
==========../../testcases_general/5-decl_float_array.cminus==========
0 0
==========../../testcases_general/6-num_add_int.cminus==========
210 210
==========../../testcases_general/7-assign_int_var_local.cminus==========
210 210
==========../../testcases_general/8-assign_int_array_local.cminus==========
210 210
==========../../testcases_general/9-assign_cast.cminus==========
5 5
==========../../testcases_general/10-funcall.cminus==========
0 0
==========../../testcases_general/11-funcall_chain.cminus==========
210 210
==========../../testcases_general/12-funcall_recursion.cminus==========
0 0
==========../../testcases_general/13-if_stmt.cminus==========
0 0
==========../../testcases_general/14-while_stmt.cminus==========
0 0
==========../../testcases_general/15-if_while.cminus==========
45 45
==========../../testcases_general/16-if_chain.cminus==========
3 3
==========../../testcases_general/17-while_chain.cminus==========
0 0
==========../../testcases_general/18-global_var.cminus==========
10 10
==========../../testcases_general/19-global_local_var.cminus==========
20 20
==========../../testcases_general/20-gcd_array.cminus==========
18 18
==========../../testcases_general/21-comment.cminus==========
0 0
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/0-io.cminus"
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define i32 @main() {
label_entry:
%op0 = call i32 @input()
call void @output(i32 %op0)
ret i32 0
}
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -32
.main_label_entry:
# %op0 = call i32 @input()
bl input
st.w $a0, $fp, -20
# call void @output(i32 %op0)
ld.w $a0, $fp, -20
bl output
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 32
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/1-return.cminus"
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define i32 @main() {
label_entry:
call void @output(i32 111)
ret i32 111
}
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -16
.main_label_entry:
# ret void
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 16
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/10-float.cminus"
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define i32 @main() {
label_entry:
%op0 = alloca float
%op1 = alloca float
%op2 = alloca float
store float 0x3ff19999a0000000, float* %op0
store float 0x3ff8000000000000, float* %op1
store float 0x3ff3333340000000, float* %op2
%op3 = load float, float* %op0
%op4 = load float, float* %op1
%op5 = fmul float %op3, %op4
%op6 = load float, float* %op2
%op7 = fadd float %op5, %op6
call void @outputFloat(float %op7)
ret i32 0
}
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -80
.main_label_entry:
# %op0 = alloca float
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = alloca float
addi.d $t0, $fp, -40
st.d $t0, $fp, -36
# %op2 = alloca float
addi.d $t0, $fp, -52
st.d $t0, $fp, -48
# store float 0x3ff19999a0000000, float* %op0
ld.d $t0, $fp, -24
lu12i.w $t8, 260300
ori $t8, $t8, 3277
movgr2fr.w $ft0, $t8
fst.s $ft0, $t0, 0
# store float 0x3ff8000000000000, float* %op1
ld.d $t0, $fp, -36
lu12i.w $t8, 261120
ori $t8, $t8, 0
movgr2fr.w $ft0, $t8
fst.s $ft0, $t0, 0
# store float 0x3ff3333340000000, float* %op2
ld.d $t0, $fp, -48
lu12i.w $t8, 260505
ori $t8, $t8, 2458
movgr2fr.w $ft0, $t8
fst.s $ft0, $t0, 0
# %op3 = load float, float* %op0
ld.d $t0, $fp, -24
fld.s $ft0, $t0, 0
fst.s $ft0, $fp, -56
# %op4 = load float, float* %op1
ld.d $t0, $fp, -36
fld.s $ft0, $t0, 0
fst.s $ft0, $fp, -60
# %op5 = fmul float %op3, %op4
fld.s $ft0, $fp, -56
fld.s $ft1, $fp, -60
fmul.s $ft2, $ft0, $ft1
fst.s $ft2, $fp, -64
# %op6 = load float, float* %op2
ld.d $t0, $fp, -48
fld.s $ft0, $t0, 0
fst.s $ft0, $fp, -68
# %op7 = fadd float %op5, %op6
fld.s $ft0, $fp, -64
fld.s $ft1, $fp, -68
fadd.s $ft2, $ft0, $ft1
fst.s $ft2, $fp, -72
# call void @outputFloat(float %op7)
fld.s $fa0, $fp, -72
bl outputFloat
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 80
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl test
.type test, @function
test:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -32
st.w $a0, $fp, -20
.test_label_entry:
# %op1 = alloca i32
addi.d $t0, $fp, -32
st.d $t0, $fp, -28
# store i32 %arg0, i32* %op1
ld.d $t0, $fp, -28
ld.w $t1, $fp, -20
st.w $t1, $t0, 0
# ret void
addi.w $a0, $zero, 0
b test_exit
test_exit:
addi.d $sp, $sp, 32
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -32
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# store i32 10, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 10
st.w $t1, $t0, 0
# %op1 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -32
# call void @test(i32 %op1)
ld.w $a0, $fp, -32
bl test
# ret void
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 32
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/11-floatcall.cminus"
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define float @mod(float %arg0, float %arg1) {
label_entry:
%op2 = alloca float
store float %arg0, float* %op2
%op3 = alloca float
store float %arg1, float* %op3
%op4 = alloca i32
%op5 = load float, float* %op2
%op6 = load float, float* %op3
%op7 = fdiv float %op5, %op6
%op8 = fptosi float %op7 to i32
store i32 %op8, i32* %op4
%op9 = load float, float* %op2
%op10 = load i32, i32* %op4
%op11 = load float, float* %op3
%op12 = sitofp i32 %op10 to float
%op13 = fmul float %op12, %op11
%op14 = fsub float %op9, %op13
ret float %op14
}
define i32 @main() {
label_entry:
%op0 = alloca float
%op1 = alloca float
store float 0x4026666660000000, float* %op0
store float 0x40019999a0000000, float* %op1
%op2 = load float, float* %op0
%op3 = load float, float* %op1
%op4 = call float @mod(float %op2, float %op3)
call void @outputFloat(float %op4)
ret i32 0
}
.text
.globl mod
.type mod, @function
mod:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -112
fst.s $fa0, $fp, -20
fst.s $fa1, $fp, -24
.mod_label_entry:
# %op2 = alloca float
addi.d $t0, $fp, -36
st.d $t0, $fp, -32
# store float %arg0, float* %op2
ld.d $t0, $fp, -32
fld.s $ft0, $fp, -20
fst.s $ft0, $t0, 0
# %op3 = alloca float
addi.d $t0, $fp, -48
st.d $t0, $fp, -44
# store float %arg1, float* %op3
ld.d $t0, $fp, -44
fld.s $ft0, $fp, -24
fst.s $ft0, $t0, 0
# %op4 = alloca i32
addi.d $t0, $fp, -60
st.d $t0, $fp, -56
# %op5 = load float, float* %op2
ld.d $t0, $fp, -32
fld.s $ft0, $t0, 0
fst.s $ft0, $fp, -64
# %op6 = load float, float* %op3
ld.d $t0, $fp, -44
fld.s $ft0, $t0, 0
fst.s $ft0, $fp, -68
# %op7 = fdiv float %op5, %op6
fld.s $ft0, $fp, -64
fld.s $ft1, $fp, -68
fdiv.s $ft2, $ft0, $ft1
fst.s $ft2, $fp, -72
# %op8 = fptosi float %op7 to i32
fld.s $ft0, $fp, -72
ftintrz.w.s $ft0, $ft0
movfr2gr.s $t0, $ft0
st.w $t0, $fp, -76
# store i32 %op8, i32* %op4
ld.d $t0, $fp, -56
ld.w $t1, $fp, -76
st.w $t1, $t0, 0
# %op9 = load float, float* %op2
ld.d $t0, $fp, -32
fld.s $ft0, $t0, 0
fst.s $ft0, $fp, -80
# %op10 = load i32, i32* %op4
ld.d $t0, $fp, -56
ld.w $t0, $t0, 0
st.w $t0, $fp, -84
# %op11 = load float, float* %op3
ld.d $t0, $fp, -44
fld.s $ft0, $t0, 0
fst.s $ft0, $fp, -88
# %op12 = sitofp i32 %op10 to float
ld.w $t0, $fp, -84
movgr2fr.w $ft0, $t0
ffint.s.w $ft0, $ft0
fst.s $ft0, $fp, -92
# %op13 = fmul float %op12, %op11
fld.s $ft0, $fp, -92
fld.s $ft1, $fp, -88
fmul.s $ft2, $ft0, $ft1
fst.s $ft2, $fp, -96
# %op14 = fsub float %op9, %op13
fld.s $ft0, $fp, -80
fld.s $ft1, $fp, -96
fsub.s $ft2, $ft0, $ft1
fst.s $ft2, $fp, -100
# ret float %op14
fld.s $fa0, $fp, -100
b mod_exit
mod_exit:
addi.d $sp, $sp, 112
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -64
.main_label_entry:
# %op0 = alloca float
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = alloca float
addi.d $t0, $fp, -40
st.d $t0, $fp, -36
# store float 0x4026666660000000, float* %op0
ld.d $t0, $fp, -24
lu12i.w $t8, 267059
ori $t8, $t8, 819
movgr2fr.w $ft0, $t8
fst.s $ft0, $t0, 0
# store float 0x40019999a0000000, float* %op1
ld.d $t0, $fp, -36
lu12i.w $t8, 262348
ori $t8, $t8, 3277
movgr2fr.w $ft0, $t8
fst.s $ft0, $t0, 0
# %op2 = load float, float* %op0
ld.d $t0, $fp, -24
fld.s $ft0, $t0, 0
fst.s $ft0, $fp, -44
# %op3 = load float, float* %op1
ld.d $t0, $fp, -36
fld.s $ft0, $t0, 0
fst.s $ft0, $fp, -48
# %op4 = call float @mod(float %op2, float %op3)
fld.s $fa0, $fp, -44
fld.s $fa1, $fp, -48
bl mod
fst.s $fa0, $fp, -52
# call void @outputFloat(float %op4)
fld.s $fa0, $fp, -52
bl outputFloat
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 64
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl addone
.type addone, @function
addone:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -48
st.w $a0, $fp, -20
.addone_label_entry:
# %op1 = alloca i32
addi.d $t0, $fp, -32
st.d $t0, $fp, -28
# store i32 %arg0, i32* %op1
ld.d $t0, $fp, -28
ld.w $t1, $fp, -20
st.w $t1, $t0, 0
# %op2 = load i32, i32* %op1
ld.d $t0, $fp, -28
ld.w $t0, $t0, 0
st.w $t0, $fp, -36
# %op3 = add i32 %op2, 1
ld.w $t0, $fp, -36
addi.w $t1, $zero, 1
add.w $t2, $t0, $t1
st.w $t2, $fp, -40
# ret i32 %op3
ld.w $a0, $fp, -40
b addone_exit
addone_exit:
addi.d $sp, $sp, 48
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -48
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = call i32 @addone(i32 1230)
addi.w $a0, $zero, 1230
bl addone
st.w $a0, $fp, -32
# %op2 = call i32 @addone(i32 %op1)
ld.w $a0, $fp, -32
bl addone
st.w $a0, $fp, -36
# %op3 = call i32 @addone(i32 %op2)
ld.w $a0, $fp, -36
bl addone
st.w $a0, $fp, -40
# %op4 = call i32 @addone(i32 %op3)
ld.w $a0, $fp, -40
bl addone
st.w $a0, $fp, -44
# store i32 %op4, i32* %op0
ld.d $t0, $fp, -24
ld.w $t1, $fp, -44
st.w $t1, $t0, 0
# %op5 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -48
# ret i32 %op5
ld.w $a0, $fp, -48
b main_exit
main_exit:
addi.d $sp, $sp, 48
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl factorial
.type factorial, @function
factorial:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -64
st.w $a0, $fp, -20
.factorial_label_entry:
# %op1 = alloca i32
addi.d $t0, $fp, -32
st.d $t0, $fp, -28
# store i32 %arg0, i32* %op1
ld.d $t0, $fp, -28
ld.w $t1, $fp, -20
st.w $t1, $t0, 0
# %op2 = load i32, i32* %op1
ld.d $t0, $fp, -28
ld.w $t0, $t0, 0
st.w $t0, $fp, -36
# %op3 = icmp eq i32 %op2, 0
ld.w $t0, $fp, -36
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltui $t2, $t2, 1
st.b $t2, $fp, -37
# %op4 = zext i1 %op3 to i32
ld.b $t0, $fp, -37
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -41
# %op5 = icmp ne i32 %op4, 0
ld.w $t0, $fp, -41
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -42
# br i1 %op5, label %label6, label %label8
ld.b $t0, $fp, -42
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .factorial_label6
b .factorial_label8
.factorial_label6:
# ret i32 1
addi.w $a0, $zero, 1
b factorial_exit
.factorial_label7:
# ret i32 0
addi.w $a0, $zero, 0
b factorial_exit
.factorial_label8:
# %op9 = load i32, i32* %op1
ld.d $t0, $fp, -28
ld.w $t0, $t0, 0
st.w $t0, $fp, -46
# %op10 = load i32, i32* %op1
ld.d $t0, $fp, -28
ld.w $t0, $t0, 0
st.w $t0, $fp, -50
# %op11 = sub i32 %op10, 1
ld.w $t0, $fp, -50
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -54
# %op12 = call i32 @factorial(i32 %op11)
ld.w $a0, $fp, -54
bl factorial
st.w $a0, $fp, -58
# %op13 = mul i32 %op9, %op12
ld.w $t0, $fp, -46
ld.w $t1, $fp, -58
mul.w $t2, $t0, $t1
st.w $t2, $fp, -62
# ret i32 %op13
ld.w $a0, $fp, -62
b factorial_exit
factorial_exit:
addi.d $sp, $sp, 64
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -48
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = call i32 @factorial(i32 10)
addi.w $a0, $zero, 10
bl factorial
st.w $a0, $fp, -32
# store i32 %op1, i32* %op0
ld.d $t0, $fp, -24
ld.w $t1, $fp, -32
st.w $t1, $t0, 0
# %op2 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -36
# ret i32 %op2
ld.w $a0, $fp, -36
b main_exit
main_exit:
addi.d $sp, $sp, 48
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/12-global.cminus"
@seed = global i32 zeroinitializer
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define i32 @randomLCG() {
label_entry:
%op0 = load i32, i32* @seed
%op1 = mul i32 %op0, 1103515245
%op2 = add i32 %op1, 12345
store i32 %op2, i32* @seed
%op3 = load i32, i32* @seed
ret i32 %op3
}
define i32 @randBin() {
label_entry:
%op0 = call i32 @randomLCG()
%op1 = icmp sgt i32 %op0, 0
%op2 = zext i1 %op1 to i32
%op3 = icmp ne i32 %op2, 0
br i1 %op3, label %label4, label %label6
label4: ; preds = %label_entry
ret i32 1
label5:
ret i32 0
label6: ; preds = %label_entry
ret i32 0
}
define i32 @returnToZeroSteps() {
label_entry:
%op0 = alloca i32
%op1 = alloca i32
store i32 0, i32* %op0
store i32 0, i32* %op1
br label %label2
label2: ; preds = %label_entry, %label26
%op3 = load i32, i32* %op1
%op4 = icmp slt i32 %op3, 20
%op5 = zext i1 %op4 to i32
%op6 = icmp ne i32 %op5, 0
br i1 %op6, label %label7, label %label10
label7: ; preds = %label2
%op8 = call i32 @randBin()
%op9 = icmp ne i32 %op8, 0
br i1 %op9, label %label11, label %label21
label10: ; preds = %label2
ret i32 20
label11: ; preds = %label7
%op12 = load i32, i32* %op0
%op13 = add i32 %op12, 1
store i32 %op13, i32* %op0
br label %label14
label14: ; preds = %label11, %label21
%op15 = load i32, i32* %op1
%op16 = add i32 %op15, 1
store i32 %op16, i32* %op1
%op17 = load i32, i32* %op0
%op18 = icmp eq i32 %op17, 0
%op19 = zext i1 %op18 to i32
%op20 = icmp ne i32 %op19, 0
br i1 %op20, label %label24, label %label26
label21: ; preds = %label7
%op22 = load i32, i32* %op0
%op23 = sub i32 %op22, 1
store i32 %op23, i32* %op0
br label %label14
label24: ; preds = %label14
%op25 = load i32, i32* %op1
ret i32 %op25
label26: ; preds = %label14
br label %label2
}
define i32 @main() {
label_entry:
%op0 = alloca i32
store i32 0, i32* %op0
store i32 3407, i32* @seed
br label %label1
label1: ; preds = %label_entry, %label6
%op2 = load i32, i32* %op0
%op3 = icmp slt i32 %op2, 20
%op4 = zext i1 %op3 to i32
%op5 = icmp ne i32 %op4, 0
br i1 %op5, label %label6, label %label10
label6: ; preds = %label1
%op7 = call i32 @returnToZeroSteps()
call void @output(i32 %op7)
%op8 = load i32, i32* %op0
%op9 = add i32 %op8, 1
store i32 %op9, i32* %op0
br label %label1
label10: ; preds = %label1
ret i32 0
}
4
2
2
4
8
2
2
2
2
2
6
2
10
8
4
2
20
2
2
8
0
# Global variables
.text
.section .bss, "aw", @nobits
.globl seed
.type seed, @object
.size seed, 4
seed:
.space 4
.text
.globl randomLCG
.type randomLCG, @function
randomLCG:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -32
.randomLCG_label_entry:
# %op0 = load i32, i32* @seed
la.local $t0, seed
ld.w $t0, $t0, 0
st.w $t0, $fp, -20
# %op1 = mul i32 %op0, 1103515245
ld.w $t0, $fp, -20
lu12i.w $t1, 269412
ori $t1, $t1, 3693
mul.w $t2, $t0, $t1
st.w $t2, $fp, -24
# %op2 = add i32 %op1, 12345
ld.w $t0, $fp, -24
lu12i.w $t1, 3
ori $t1, $t1, 57
add.w $t2, $t0, $t1
st.w $t2, $fp, -28
# store i32 %op2, i32* @seed
la.local $t0, seed
ld.w $t1, $fp, -28
st.w $t1, $t0, 0
# %op3 = load i32, i32* @seed
la.local $t0, seed
ld.w $t0, $t0, 0
st.w $t0, $fp, -32
# ret i32 %op3
ld.w $a0, $fp, -32
b randomLCG_exit
randomLCG_exit:
addi.d $sp, $sp, 32
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl randBin
.type randBin, @function
randBin:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -32
.randBin_label_entry:
# %op0 = call i32 @randomLCG()
bl randomLCG
st.w $a0, $fp, -20
# %op1 = icmp sgt i32 %op0, 0
ld.w $t0, $fp, -20
addi.w $t1, $zero, 0
slt $t2, $t1, $t0
st.b $t2, $fp, -21
# %op2 = zext i1 %op1 to i32
ld.b $t0, $fp, -21
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -25
# %op3 = icmp ne i32 %op2, 0
ld.w $t0, $fp, -25
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -26
# br i1 %op3, label %label4, label %label6
ld.b $t0, $fp, -26
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .randBin_label4
b .randBin_label6
.randBin_label4:
# ret i32 1
addi.w $a0, $zero, 1
b randBin_exit
.randBin_label5:
# ret i32 0
addi.w $a0, $zero, 0
b randBin_exit
.randBin_label6:
# ret i32 0
addi.w $a0, $zero, 0
b randBin_exit
randBin_exit:
addi.d $sp, $sp, 32
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl returnToZeroSteps
.type returnToZeroSteps, @function
returnToZeroSteps:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -96
.returnToZeroSteps_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = alloca i32
addi.d $t0, $fp, -40
st.d $t0, $fp, -36
# store i32 0, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 0
st.w $t1, $t0, 0
# store i32 0, i32* %op1
ld.d $t0, $fp, -36
addi.w $t1, $zero, 0
st.w $t1, $t0, 0
# br label %label2
b .returnToZeroSteps_label2
.returnToZeroSteps_label2:
# %op3 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -44
# %op4 = icmp slt i32 %op3, 20
ld.w $t0, $fp, -44
addi.w $t1, $zero, 20
slt $t2, $t0, $t1
st.b $t2, $fp, -45
# %op5 = zext i1 %op4 to i32
ld.b $t0, $fp, -45
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -49
# %op6 = icmp ne i32 %op5, 0
ld.w $t0, $fp, -49
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -50
# br i1 %op6, label %label7, label %label10
ld.b $t0, $fp, -50
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .returnToZeroSteps_label7
b .returnToZeroSteps_label10
.returnToZeroSteps_label7:
# %op8 = call i32 @randBin()
bl randBin
st.w $a0, $fp, -54
# %op9 = icmp ne i32 %op8, 0
ld.w $t0, $fp, -54
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -55
# br i1 %op9, label %label11, label %label21
ld.b $t0, $fp, -55
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .returnToZeroSteps_label11
b .returnToZeroSteps_label21
.returnToZeroSteps_label10:
# ret i32 20
addi.w $a0, $zero, 20
b returnToZeroSteps_exit
.returnToZeroSteps_label11:
# %op12 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -59
# %op13 = add i32 %op12, 1
ld.w $t0, $fp, -59
addi.w $t1, $zero, 1
add.w $t2, $t0, $t1
st.w $t2, $fp, -63
# store i32 %op13, i32* %op0
ld.d $t0, $fp, -24
ld.w $t1, $fp, -63
st.w $t1, $t0, 0
# br label %label14
b .returnToZeroSteps_label14
.returnToZeroSteps_label14:
# %op15 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -67
# %op16 = add i32 %op15, 1
ld.w $t0, $fp, -67
addi.w $t1, $zero, 1
add.w $t2, $t0, $t1
st.w $t2, $fp, -71
# store i32 %op16, i32* %op1
ld.d $t0, $fp, -36
ld.w $t1, $fp, -71
st.w $t1, $t0, 0
# %op17 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -75
# %op18 = icmp eq i32 %op17, 0
ld.w $t0, $fp, -75
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltui $t2, $t2, 1
st.b $t2, $fp, -76
# %op19 = zext i1 %op18 to i32
ld.b $t0, $fp, -76
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -80
# %op20 = icmp ne i32 %op19, 0
ld.w $t0, $fp, -80
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -81
# br i1 %op20, label %label24, label %label26
ld.b $t0, $fp, -81
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .returnToZeroSteps_label24
b .returnToZeroSteps_label26
.returnToZeroSteps_label21:
# %op22 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -85
# %op23 = sub i32 %op22, 1
ld.w $t0, $fp, -85
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -89
# store i32 %op23, i32* %op0
ld.d $t0, $fp, -24
ld.w $t1, $fp, -89
st.w $t1, $t0, 0
# br label %label14
b .returnToZeroSteps_label14
.returnToZeroSteps_label24:
# %op25 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -93
# ret i32 %op25
ld.w $a0, $fp, -93
b returnToZeroSteps_exit
.returnToZeroSteps_label26:
# br label %label2
b .returnToZeroSteps_label2
returnToZeroSteps_exit:
addi.d $sp, $sp, 96
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -64
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# store i32 0, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 0
st.w $t1, $t0, 0
# store i32 3407, i32* @seed
la.local $t0, seed
lu12i.w $t1, 0
ori $t1, $t1, 3407
st.w $t1, $t0, 0
# br label %label1
b .main_label1
.main_label1:
# %op2 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -32
# %op3 = icmp slt i32 %op2, 20
ld.w $t0, $fp, -32
addi.w $t1, $zero, 20
slt $t2, $t0, $t1
st.b $t2, $fp, -33
# %op4 = zext i1 %op3 to i32
ld.b $t0, $fp, -33
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -37
# %op5 = icmp ne i32 %op4, 0
ld.w $t0, $fp, -37
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -38
# br i1 %op5, label %label6, label %label10
ld.b $t0, $fp, -38
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label6
b .main_label10
.main_label6:
# %op7 = call i32 @returnToZeroSteps()
bl returnToZeroSteps
st.w $a0, $fp, -42
# call void @output(i32 %op7)
ld.w $a0, $fp, -42
bl output
# %op8 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -46
# %op9 = add i32 %op8, 1
ld.w $t0, $fp, -46
addi.w $t1, $zero, 1
add.w $t2, $t0, $t1
st.w $t2, $fp, -50
# store i32 %op9, i32* %op0
ld.d $t0, $fp, -24
ld.w $t1, $fp, -50
st.w $t1, $t0, 0
# br label %label1
b .main_label1
.main_label10:
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 64
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/13-complex.cminus"
@n = global i32 zeroinitializer
@m = global i32 zeroinitializer
@w = global [5 x i32] zeroinitializer
@v = global [5 x i32] zeroinitializer
@dp = global [66 x i32] zeroinitializer
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define i32 @max(i32 %arg0, i32 %arg1) {
label_entry:
%op2 = alloca i32
store i32 %arg0, i32* %op2
%op3 = alloca i32
store i32 %arg1, i32* %op3
%op4 = load i32, i32* %op2
%op5 = load i32, i32* %op3
%op6 = icmp sgt i32 %op4, %op5
%op7 = zext i1 %op6 to i32
%op8 = icmp ne i32 %op7, 0
br i1 %op8, label %label9, label %label12
label9: ; preds = %label_entry
%op10 = load i32, i32* %op2
ret i32 %op10
label11:
ret i32 0
label12: ; preds = %label_entry
%op13 = load i32, i32* %op3
ret i32 %op13
}
define i32 @knapsack(i32 %arg0, i32 %arg1) {
label_entry:
%op2 = alloca i32
store i32 %arg0, i32* %op2
%op3 = alloca i32
store i32 %arg1, i32* %op3
%op4 = alloca i32
%op5 = load i32, i32* %op3
%op6 = icmp sle i32 %op5, 0
%op7 = zext i1 %op6 to i32
%op8 = icmp ne i32 %op7, 0
br i1 %op8, label %label9, label %label10
label9: ; preds = %label_entry
ret i32 0
label10: ; preds = %label_entry
%op11 = load i32, i32* %op2
%op12 = icmp eq i32 %op11, 0
%op13 = zext i1 %op12 to i32
%op14 = icmp ne i32 %op13, 0
br i1 %op14, label %label15, label %label16
label15: ; preds = %label10
ret i32 0
label16: ; preds = %label10
%op17 = load i32, i32* %op2
%op18 = mul i32 %op17, 11
%op19 = load i32, i32* %op3
%op20 = add i32 %op18, %op19
%op21 = icmp slt i32 %op20, 0
br i1 %op21, label %label22, label %label23
label22: ; preds = %label16
call void @neg_idx_except()
ret i32 0
label23: ; preds = %label16
%op24 = getelementptr [66 x i32], [66 x i32]* @dp, i32 0, i32 %op20
%op25 = load i32, i32* %op24
%op26 = icmp sge i32 %op25, 0
%op27 = zext i1 %op26 to i32
%op28 = icmp ne i32 %op27, 0
br i1 %op28, label %label29, label %label35
label29: ; preds = %label23
%op30 = load i32, i32* %op2
%op31 = mul i32 %op30, 11
%op32 = load i32, i32* %op3
%op33 = add i32 %op31, %op32
%op34 = icmp slt i32 %op33, 0
br i1 %op34, label %label40, label %label41
label35: ; preds = %label23
%op36 = load i32, i32* %op3
%op37 = load i32, i32* %op2
%op38 = sub i32 %op37, 1
%op39 = icmp slt i32 %op38, 0
br i1 %op39, label %label44, label %label45
label40: ; preds = %label29
call void @neg_idx_except()
ret i32 0
label41: ; preds = %label29
%op42 = getelementptr [66 x i32], [66 x i32]* @dp, i32 0, i32 %op33
%op43 = load i32, i32* %op42
ret i32 %op43
label44: ; preds = %label35
call void @neg_idx_except()
ret i32 0
label45: ; preds = %label35
%op46 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 %op38
%op47 = load i32, i32* %op46
%op48 = icmp slt i32 %op36, %op47
%op49 = zext i1 %op48 to i32
%op50 = icmp ne i32 %op49, 0
br i1 %op50, label %label51, label %label63
label51: ; preds = %label45
%op52 = load i32, i32* %op2
%op53 = sub i32 %op52, 1
%op54 = load i32, i32* %op3
%op55 = call i32 @knapsack(i32 %op53, i32 %op54)
store i32 %op55, i32* %op4
br label %label56
label56: ; preds = %label51, %label84
%op57 = load i32, i32* %op4
%op58 = load i32, i32* %op2
%op59 = mul i32 %op58, 11
%op60 = load i32, i32* %op3
%op61 = add i32 %op59, %op60
%op62 = icmp slt i32 %op61, 0
br i1 %op62, label %label89, label %label90
label63: ; preds = %label45
%op64 = load i32, i32* %op2
%op65 = sub i32 %op64, 1
%op66 = load i32, i32* %op3
%op67 = call i32 @knapsack(i32 %op65, i32 %op66)
%op68 = load i32, i32* %op2
%op69 = sub i32 %op68, 1
%op70 = load i32, i32* %op3
%op71 = load i32, i32* %op2
%op72 = sub i32 %op71, 1
%op73 = icmp slt i32 %op72, 0
br i1 %op73, label %label74, label %label75
label74: ; preds = %label63
call void @neg_idx_except()
ret i32 0
label75: ; preds = %label63
%op76 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 %op72
%op77 = load i32, i32* %op76
%op78 = sub i32 %op70, %op77
%op79 = call i32 @knapsack(i32 %op69, i32 %op78)
%op80 = load i32, i32* %op2
%op81 = sub i32 %op80, 1
%op82 = icmp slt i32 %op81, 0
br i1 %op82, label %label83, label %label84
label83: ; preds = %label75
call void @neg_idx_except()
ret i32 0
label84: ; preds = %label75
%op85 = getelementptr [5 x i32], [5 x i32]* @v, i32 0, i32 %op81
%op86 = load i32, i32* %op85
%op87 = add i32 %op79, %op86
%op88 = call i32 @max(i32 %op67, i32 %op87)
store i32 %op88, i32* %op4
br label %label56
label89: ; preds = %label56
call void @neg_idx_except()
ret i32 0
label90: ; preds = %label56
%op91 = getelementptr [66 x i32], [66 x i32]* @dp, i32 0, i32 %op61
store i32 %op57, i32* %op91
%op92 = load i32, i32* %op4
ret i32 %op92
}
define i32 @main() {
label_entry:
%op0 = alloca i32
store i32 0, i32* %op0
store i32 5, i32* @n
store i32 10, i32* @m
%op1 = icmp slt i32 0, 0
br i1 %op1, label %label2, label %label3
label2: ; preds = %label_entry
call void @neg_idx_except()
ret i32 0
label3: ; preds = %label_entry
%op4 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 0
store i32 2, i32* %op4
%op5 = icmp slt i32 1, 0
br i1 %op5, label %label6, label %label7
label6: ; preds = %label3
call void @neg_idx_except()
ret i32 0
label7: ; preds = %label3
%op8 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 1
store i32 2, i32* %op8
%op9 = icmp slt i32 2, 0
br i1 %op9, label %label10, label %label11
label10: ; preds = %label7
call void @neg_idx_except()
ret i32 0
label11: ; preds = %label7
%op12 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 2
store i32 6, i32* %op12
%op13 = icmp slt i32 3, 0
br i1 %op13, label %label14, label %label15
label14: ; preds = %label11
call void @neg_idx_except()
ret i32 0
label15: ; preds = %label11
%op16 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 3
store i32 5, i32* %op16
%op17 = icmp slt i32 4, 0
br i1 %op17, label %label18, label %label19
label18: ; preds = %label15
call void @neg_idx_except()
ret i32 0
label19: ; preds = %label15
%op20 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 4
store i32 4, i32* %op20
%op21 = icmp slt i32 0, 0
br i1 %op21, label %label22, label %label23
label22: ; preds = %label19
call void @neg_idx_except()
ret i32 0
label23: ; preds = %label19
%op24 = getelementptr [5 x i32], [5 x i32]* @v, i32 0, i32 0
store i32 6, i32* %op24
%op25 = icmp slt i32 1, 0
br i1 %op25, label %label26, label %label27
label26: ; preds = %label23
call void @neg_idx_except()
ret i32 0
label27: ; preds = %label23
%op28 = getelementptr [5 x i32], [5 x i32]* @v, i32 0, i32 1
store i32 3, i32* %op28
%op29 = icmp slt i32 2, 0
br i1 %op29, label %label30, label %label31
label30: ; preds = %label27
call void @neg_idx_except()
ret i32 0
label31: ; preds = %label27
%op32 = getelementptr [5 x i32], [5 x i32]* @v, i32 0, i32 2
store i32 5, i32* %op32
%op33 = icmp slt i32 3, 0
br i1 %op33, label %label34, label %label35
label34: ; preds = %label31
call void @neg_idx_except()
ret i32 0
label35: ; preds = %label31
%op36 = getelementptr [5 x i32], [5 x i32]* @v, i32 0, i32 3
store i32 4, i32* %op36
%op37 = icmp slt i32 4, 0
br i1 %op37, label %label38, label %label39
label38: ; preds = %label35
call void @neg_idx_except()
ret i32 0
label39: ; preds = %label35
%op40 = getelementptr [5 x i32], [5 x i32]* @v, i32 0, i32 4
store i32 6, i32* %op40
br label %label41
label41: ; preds = %label39, %label55
%op42 = load i32, i32* %op0
%op43 = icmp slt i32 %op42, 66
%op44 = zext i1 %op43 to i32
%op45 = icmp ne i32 %op44, 0
br i1 %op45, label %label46, label %label50
label46: ; preds = %label41
%op47 = sub i32 0, 1
%op48 = load i32, i32* %op0
%op49 = icmp slt i32 %op48, 0
br i1 %op49, label %label54, label %label55
label50: ; preds = %label41
%op51 = load i32, i32* @n
%op52 = load i32, i32* @m
%op53 = call i32 @knapsack(i32 %op51, i32 %op52)
call void @output(i32 %op53)
ret i32 0
label54: ; preds = %label46
call void @neg_idx_except()
ret i32 0
label55: ; preds = %label46
%op56 = getelementptr [66 x i32], [66 x i32]* @dp, i32 0, i32 %op48
store i32 %op47, i32* %op56
%op57 = load i32, i32* %op0
%op58 = add i32 %op57, 1
store i32 %op58, i32* %op0
br label %label41
}
# Global variables
.text
.section .bss, "aw", @nobits
.globl n
.type n, @object
.size n, 4
n:
.space 4
.globl m
.type m, @object
.size m, 4
m:
.space 4
.globl w
.type w, @object
.size w, 20
w:
.space 20
.globl v
.type v, @object
.size v, 20
v:
.space 20
.globl dp
.type dp, @object
.size dp, 264
dp:
.space 264
.text
.globl max
.type max, @function
max:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -80
st.w $a0, $fp, -20
st.w $a1, $fp, -24
.max_label_entry:
# %op2 = alloca i32
addi.d $t0, $fp, -36
st.d $t0, $fp, -32
# store i32 %arg0, i32* %op2
ld.d $t0, $fp, -32
ld.w $t1, $fp, -20
st.w $t1, $t0, 0
# %op3 = alloca i32
addi.d $t0, $fp, -48
st.d $t0, $fp, -44
# store i32 %arg1, i32* %op3
ld.d $t0, $fp, -44
ld.w $t1, $fp, -24
st.w $t1, $t0, 0
# %op4 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -52
# %op5 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -56
# %op6 = icmp sgt i32 %op4, %op5
ld.w $t0, $fp, -52
ld.w $t1, $fp, -56
slt $t2, $t1, $t0
st.b $t2, $fp, -57
# %op7 = zext i1 %op6 to i32
ld.b $t0, $fp, -57
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -61
# %op8 = icmp ne i32 %op7, 0
ld.w $t0, $fp, -61
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -62
# br i1 %op8, label %label9, label %label12
ld.b $t0, $fp, -62
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .max_label9
b .max_label12
.max_label9:
# %op10 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -66
# ret i32 %op10
ld.w $a0, $fp, -66
b max_exit
.max_label11:
# ret i32 0
addi.w $a0, $zero, 0
b max_exit
.max_label12:
# %op13 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -70
# ret i32 %op13
ld.w $a0, $fp, -70
b max_exit
max_exit:
addi.d $sp, $sp, 80
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl knapsack
.type knapsack, @function
knapsack:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -320
st.w $a0, $fp, -20
st.w $a1, $fp, -24
.knapsack_label_entry:
# %op2 = alloca i32
addi.d $t0, $fp, -36
st.d $t0, $fp, -32
# store i32 %arg0, i32* %op2
ld.d $t0, $fp, -32
ld.w $t1, $fp, -20
st.w $t1, $t0, 0
# %op3 = alloca i32
addi.d $t0, $fp, -48
st.d $t0, $fp, -44
# store i32 %arg1, i32* %op3
ld.d $t0, $fp, -44
ld.w $t1, $fp, -24
st.w $t1, $t0, 0
# %op4 = alloca i32
addi.d $t0, $fp, -60
st.d $t0, $fp, -56
# %op5 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -64
# %op6 = icmp sle i32 %op5, 0
ld.w $t0, $fp, -64
addi.w $t1, $zero, 0
slt $t2, $t1, $t0
xori $t2, $t2, 1
st.b $t2, $fp, -65
# %op7 = zext i1 %op6 to i32
ld.b $t0, $fp, -65
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -69
# %op8 = icmp ne i32 %op7, 0
ld.w $t0, $fp, -69
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -70
# br i1 %op8, label %label9, label %label10
ld.b $t0, $fp, -70
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .knapsack_label9
b .knapsack_label10
.knapsack_label9:
# ret i32 0
addi.w $a0, $zero, 0
b knapsack_exit
.knapsack_label10:
# %op11 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -74
# %op12 = icmp eq i32 %op11, 0
ld.w $t0, $fp, -74
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltui $t2, $t2, 1
st.b $t2, $fp, -75
# %op13 = zext i1 %op12 to i32
ld.b $t0, $fp, -75
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -79
# %op14 = icmp ne i32 %op13, 0
ld.w $t0, $fp, -79
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -80
# br i1 %op14, label %label15, label %label16
ld.b $t0, $fp, -80
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .knapsack_label15
b .knapsack_label16
.knapsack_label15:
# ret i32 0
addi.w $a0, $zero, 0
b knapsack_exit
.knapsack_label16:
# %op17 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -84
# %op18 = mul i32 %op17, 11
ld.w $t0, $fp, -84
addi.w $t1, $zero, 11
mul.w $t2, $t0, $t1
st.w $t2, $fp, -88
# %op19 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -92
# %op20 = add i32 %op18, %op19
ld.w $t0, $fp, -88
ld.w $t1, $fp, -92
add.w $t2, $t0, $t1
st.w $t2, $fp, -96
# %op21 = icmp slt i32 %op20, 0
ld.w $t0, $fp, -96
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -97
# br i1 %op21, label %label22, label %label23
ld.b $t0, $fp, -97
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .knapsack_label22
b .knapsack_label23
.knapsack_label22:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b knapsack_exit
.knapsack_label23:
# %op24 = getelementptr [66 x i32], [66 x i32]* @dp, i32 0, i32 %op20
la.local $t0, dp
addi.w $t1, $zero, 0
addi.d $t2, $zero, 264
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
ld.w $t1, $fp, -96
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -105
# %op25 = load i32, i32* %op24
ld.d $t0, $fp, -105
ld.w $t0, $t0, 0
st.w $t0, $fp, -109
# %op26 = icmp sge i32 %op25, 0
ld.w $t0, $fp, -109
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
xori $t2, $t2, 1
st.b $t2, $fp, -110
# %op27 = zext i1 %op26 to i32
ld.b $t0, $fp, -110
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -114
# %op28 = icmp ne i32 %op27, 0
ld.w $t0, $fp, -114
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -115
# br i1 %op28, label %label29, label %label35
ld.b $t0, $fp, -115
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .knapsack_label29
b .knapsack_label35
.knapsack_label29:
# %op30 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -119
# %op31 = mul i32 %op30, 11
ld.w $t0, $fp, -119
addi.w $t1, $zero, 11
mul.w $t2, $t0, $t1
st.w $t2, $fp, -123
# %op32 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -127
# %op33 = add i32 %op31, %op32
ld.w $t0, $fp, -123
ld.w $t1, $fp, -127
add.w $t2, $t0, $t1
st.w $t2, $fp, -131
# %op34 = icmp slt i32 %op33, 0
ld.w $t0, $fp, -131
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -132
# br i1 %op34, label %label40, label %label41
ld.b $t0, $fp, -132
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .knapsack_label40
b .knapsack_label41
.knapsack_label35:
# %op36 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -136
# %op37 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -140
# %op38 = sub i32 %op37, 1
ld.w $t0, $fp, -140
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -144
# %op39 = icmp slt i32 %op38, 0
ld.w $t0, $fp, -144
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -145
# br i1 %op39, label %label44, label %label45
ld.b $t0, $fp, -145
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .knapsack_label44
b .knapsack_label45
.knapsack_label40:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b knapsack_exit
.knapsack_label41:
# %op42 = getelementptr [66 x i32], [66 x i32]* @dp, i32 0, i32 %op33
la.local $t0, dp
addi.w $t1, $zero, 0
addi.d $t2, $zero, 264
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
ld.w $t1, $fp, -131
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -153
# %op43 = load i32, i32* %op42
ld.d $t0, $fp, -153
ld.w $t0, $t0, 0
st.w $t0, $fp, -157
# ret i32 %op43
ld.w $a0, $fp, -157
b knapsack_exit
.knapsack_label44:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b knapsack_exit
.knapsack_label45:
# %op46 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 %op38
la.local $t0, w
addi.w $t1, $zero, 0
addi.d $t2, $zero, 20
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
ld.w $t1, $fp, -144
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -165
# %op47 = load i32, i32* %op46
ld.d $t0, $fp, -165
ld.w $t0, $t0, 0
st.w $t0, $fp, -169
# %op48 = icmp slt i32 %op36, %op47
ld.w $t0, $fp, -136
ld.w $t1, $fp, -169
slt $t2, $t0, $t1
st.b $t2, $fp, -170
# %op49 = zext i1 %op48 to i32
ld.b $t0, $fp, -170
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -174
# %op50 = icmp ne i32 %op49, 0
ld.w $t0, $fp, -174
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -175
# br i1 %op50, label %label51, label %label63
ld.b $t0, $fp, -175
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .knapsack_label51
b .knapsack_label63
.knapsack_label51:
# %op52 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -179
# %op53 = sub i32 %op52, 1
ld.w $t0, $fp, -179
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -183
# %op54 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -187
# %op55 = call i32 @knapsack(i32 %op53, i32 %op54)
ld.w $a0, $fp, -183
ld.w $a1, $fp, -187
bl knapsack
st.w $a0, $fp, -191
# store i32 %op55, i32* %op4
ld.d $t0, $fp, -56
ld.w $t1, $fp, -191
st.w $t1, $t0, 0
# br label %label56
b .knapsack_label56
.knapsack_label56:
# %op57 = load i32, i32* %op4
ld.d $t0, $fp, -56
ld.w $t0, $t0, 0
st.w $t0, $fp, -195
# %op58 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -199
# %op59 = mul i32 %op58, 11
ld.w $t0, $fp, -199
addi.w $t1, $zero, 11
mul.w $t2, $t0, $t1
st.w $t2, $fp, -203
# %op60 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -207
# %op61 = add i32 %op59, %op60
ld.w $t0, $fp, -203
ld.w $t1, $fp, -207
add.w $t2, $t0, $t1
st.w $t2, $fp, -211
# %op62 = icmp slt i32 %op61, 0
ld.w $t0, $fp, -211
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -212
# br i1 %op62, label %label89, label %label90
ld.b $t0, $fp, -212
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .knapsack_label89
b .knapsack_label90
.knapsack_label63:
# %op64 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -216
# %op65 = sub i32 %op64, 1
ld.w $t0, $fp, -216
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -220
# %op66 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -224
# %op67 = call i32 @knapsack(i32 %op65, i32 %op66)
ld.w $a0, $fp, -220
ld.w $a1, $fp, -224
bl knapsack
st.w $a0, $fp, -228
# %op68 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -232
# %op69 = sub i32 %op68, 1
ld.w $t0, $fp, -232
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -236
# %op70 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -240
# %op71 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -244
# %op72 = sub i32 %op71, 1
ld.w $t0, $fp, -244
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -248
# %op73 = icmp slt i32 %op72, 0
ld.w $t0, $fp, -248
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -249
# br i1 %op73, label %label74, label %label75
ld.b $t0, $fp, -249
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .knapsack_label74
b .knapsack_label75
.knapsack_label74:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b knapsack_exit
.knapsack_label75:
# %op76 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 %op72
la.local $t0, w
addi.w $t1, $zero, 0
addi.d $t2, $zero, 20
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
ld.w $t1, $fp, -248
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -257
# %op77 = load i32, i32* %op76
ld.d $t0, $fp, -257
ld.w $t0, $t0, 0
st.w $t0, $fp, -261
# %op78 = sub i32 %op70, %op77
ld.w $t0, $fp, -240
ld.w $t1, $fp, -261
sub.w $t2, $t0, $t1
st.w $t2, $fp, -265
# %op79 = call i32 @knapsack(i32 %op69, i32 %op78)
ld.w $a0, $fp, -236
ld.w $a1, $fp, -265
bl knapsack
st.w $a0, $fp, -269
# %op80 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -273
# %op81 = sub i32 %op80, 1
ld.w $t0, $fp, -273
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -277
# %op82 = icmp slt i32 %op81, 0
ld.w $t0, $fp, -277
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -278
# br i1 %op82, label %label83, label %label84
ld.b $t0, $fp, -278
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .knapsack_label83
b .knapsack_label84
.knapsack_label83:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b knapsack_exit
.knapsack_label84:
# %op85 = getelementptr [5 x i32], [5 x i32]* @v, i32 0, i32 %op81
la.local $t0, v
addi.w $t1, $zero, 0
addi.d $t2, $zero, 20
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
ld.w $t1, $fp, -277
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -286
# %op86 = load i32, i32* %op85
ld.d $t0, $fp, -286
ld.w $t0, $t0, 0
st.w $t0, $fp, -290
# %op87 = add i32 %op79, %op86
ld.w $t0, $fp, -269
ld.w $t1, $fp, -290
add.w $t2, $t0, $t1
st.w $t2, $fp, -294
# %op88 = call i32 @max(i32 %op67, i32 %op87)
ld.w $a0, $fp, -228
ld.w $a1, $fp, -294
bl max
st.w $a0, $fp, -298
# store i32 %op88, i32* %op4
ld.d $t0, $fp, -56
ld.w $t1, $fp, -298
st.w $t1, $t0, 0
# br label %label56
b .knapsack_label56
.knapsack_label89:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b knapsack_exit
.knapsack_label90:
# %op91 = getelementptr [66 x i32], [66 x i32]* @dp, i32 0, i32 %op61
la.local $t0, dp
addi.w $t1, $zero, 0
addi.d $t2, $zero, 264
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
ld.w $t1, $fp, -211
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -306
# store i32 %op57, i32* %op91
ld.d $t0, $fp, -306
ld.w $t1, $fp, -195
st.w $t1, $t0, 0
# %op92 = load i32, i32* %op4
ld.d $t0, $fp, -56
ld.w $t0, $t0, 0
st.w $t0, $fp, -310
# ret i32 %op92
ld.w $a0, $fp, -310
b knapsack_exit
knapsack_exit:
addi.d $sp, $sp, 320
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -176
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# store i32 0, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 0
st.w $t1, $t0, 0
# store i32 5, i32* @n
la.local $t0, n
addi.w $t1, $zero, 5
st.w $t1, $t0, 0
# store i32 10, i32* @m
la.local $t0, m
addi.w $t1, $zero, 10
st.w $t1, $t0, 0
# %op1 = icmp slt i32 0, 0
addi.w $t0, $zero, 0
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -29
# br i1 %op1, label %label2, label %label3
ld.b $t0, $fp, -29
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label2
b .main_label3
.main_label2:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label3:
# %op4 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 0
la.local $t0, w
addi.w $t1, $zero, 0
addi.d $t2, $zero, 20
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -37
# store i32 2, i32* %op4
ld.d $t0, $fp, -37
addi.w $t1, $zero, 2
st.w $t1, $t0, 0
# %op5 = icmp slt i32 1, 0
addi.w $t0, $zero, 1
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -38
# br i1 %op5, label %label6, label %label7
ld.b $t0, $fp, -38
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label6
b .main_label7
.main_label6:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label7:
# %op8 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 1
la.local $t0, w
addi.w $t1, $zero, 0
addi.d $t2, $zero, 20
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 1
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -46
# store i32 2, i32* %op8
ld.d $t0, $fp, -46
addi.w $t1, $zero, 2
st.w $t1, $t0, 0
# %op9 = icmp slt i32 2, 0
addi.w $t0, $zero, 2
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -47
# br i1 %op9, label %label10, label %label11
ld.b $t0, $fp, -47
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label10
b .main_label11
.main_label10:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label11:
# %op12 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 2
la.local $t0, w
addi.w $t1, $zero, 0
addi.d $t2, $zero, 20
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 2
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -55
# store i32 6, i32* %op12
ld.d $t0, $fp, -55
addi.w $t1, $zero, 6
st.w $t1, $t0, 0
# %op13 = icmp slt i32 3, 0
addi.w $t0, $zero, 3
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -56
# br i1 %op13, label %label14, label %label15
ld.b $t0, $fp, -56
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label14
b .main_label15
.main_label14:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label15:
# %op16 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 3
la.local $t0, w
addi.w $t1, $zero, 0
addi.d $t2, $zero, 20
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 3
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -64
# store i32 5, i32* %op16
ld.d $t0, $fp, -64
addi.w $t1, $zero, 5
st.w $t1, $t0, 0
# %op17 = icmp slt i32 4, 0
addi.w $t0, $zero, 4
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -65
# br i1 %op17, label %label18, label %label19
ld.b $t0, $fp, -65
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label18
b .main_label19
.main_label18:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label19:
# %op20 = getelementptr [5 x i32], [5 x i32]* @w, i32 0, i32 4
la.local $t0, w
addi.w $t1, $zero, 0
addi.d $t2, $zero, 20
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 4
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -73
# store i32 4, i32* %op20
ld.d $t0, $fp, -73
addi.w $t1, $zero, 4
st.w $t1, $t0, 0
# %op21 = icmp slt i32 0, 0
addi.w $t0, $zero, 0
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -74
# br i1 %op21, label %label22, label %label23
ld.b $t0, $fp, -74
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label22
b .main_label23
.main_label22:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label23:
# %op24 = getelementptr [5 x i32], [5 x i32]* @v, i32 0, i32 0
la.local $t0, v
addi.w $t1, $zero, 0
addi.d $t2, $zero, 20
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -82
# store i32 6, i32* %op24
ld.d $t0, $fp, -82
addi.w $t1, $zero, 6
st.w $t1, $t0, 0
# %op25 = icmp slt i32 1, 0
addi.w $t0, $zero, 1
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -83
# br i1 %op25, label %label26, label %label27
ld.b $t0, $fp, -83
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label26
b .main_label27
.main_label26:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label27:
# %op28 = getelementptr [5 x i32], [5 x i32]* @v, i32 0, i32 1
la.local $t0, v
addi.w $t1, $zero, 0
addi.d $t2, $zero, 20
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 1
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -91
# store i32 3, i32* %op28
ld.d $t0, $fp, -91
addi.w $t1, $zero, 3
st.w $t1, $t0, 0
# %op29 = icmp slt i32 2, 0
addi.w $t0, $zero, 2
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -92
# br i1 %op29, label %label30, label %label31
ld.b $t0, $fp, -92
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label30
b .main_label31
.main_label30:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label31:
# %op32 = getelementptr [5 x i32], [5 x i32]* @v, i32 0, i32 2
la.local $t0, v
addi.w $t1, $zero, 0
addi.d $t2, $zero, 20
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 2
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -100
# store i32 5, i32* %op32
ld.d $t0, $fp, -100
addi.w $t1, $zero, 5
st.w $t1, $t0, 0
# %op33 = icmp slt i32 3, 0
addi.w $t0, $zero, 3
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -101
# br i1 %op33, label %label34, label %label35
ld.b $t0, $fp, -101
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label34
b .main_label35
.main_label34:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label35:
# %op36 = getelementptr [5 x i32], [5 x i32]* @v, i32 0, i32 3
la.local $t0, v
addi.w $t1, $zero, 0
addi.d $t2, $zero, 20
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 3
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -109
# store i32 4, i32* %op36
ld.d $t0, $fp, -109
addi.w $t1, $zero, 4
st.w $t1, $t0, 0
# %op37 = icmp slt i32 4, 0
addi.w $t0, $zero, 4
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -110
# br i1 %op37, label %label38, label %label39
ld.b $t0, $fp, -110
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label38
b .main_label39
.main_label38:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label39:
# %op40 = getelementptr [5 x i32], [5 x i32]* @v, i32 0, i32 4
la.local $t0, v
addi.w $t1, $zero, 0
addi.d $t2, $zero, 20
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 4
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -118
# store i32 6, i32* %op40
ld.d $t0, $fp, -118
addi.w $t1, $zero, 6
st.w $t1, $t0, 0
# br label %label41
b .main_label41
.main_label41:
# %op42 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -122
# %op43 = icmp slt i32 %op42, 66
ld.w $t0, $fp, -122
addi.w $t1, $zero, 66
slt $t2, $t0, $t1
st.b $t2, $fp, -123
# %op44 = zext i1 %op43 to i32
ld.b $t0, $fp, -123
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -127
# %op45 = icmp ne i32 %op44, 0
ld.w $t0, $fp, -127
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -128
# br i1 %op45, label %label46, label %label50
ld.b $t0, $fp, -128
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label46
b .main_label50
.main_label46:
# %op47 = sub i32 0, 1
addi.w $t0, $zero, 0
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -132
# %op48 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -136
# %op49 = icmp slt i32 %op48, 0
ld.w $t0, $fp, -136
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -137
# br i1 %op49, label %label54, label %label55
ld.b $t0, $fp, -137
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label54
b .main_label55
.main_label50:
# %op51 = load i32, i32* @n
la.local $t0, n
ld.w $t0, $t0, 0
st.w $t0, $fp, -141
# %op52 = load i32, i32* @m
la.local $t0, m
ld.w $t0, $t0, 0
st.w $t0, $fp, -145
# %op53 = call i32 @knapsack(i32 %op51, i32 %op52)
ld.w $a0, $fp, -141
ld.w $a1, $fp, -145
bl knapsack
st.w $a0, $fp, -149
# call void @output(i32 %op53)
ld.w $a0, $fp, -149
bl output
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label54:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label55:
# %op56 = getelementptr [66 x i32], [66 x i32]* @dp, i32 0, i32 %op48
la.local $t0, dp
addi.w $t1, $zero, 0
addi.d $t2, $zero, 264
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
ld.w $t1, $fp, -136
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -157
# store i32 %op47, i32* %op56
ld.d $t0, $fp, -157
ld.w $t1, $fp, -132
st.w $t1, $t0, 0
# %op57 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -161
# %op58 = add i32 %op57, 1
ld.w $t0, $fp, -161
addi.w $t1, $zero, 1
add.w $t2, $t0, $t1
st.w $t2, $fp, -165
# store i32 %op58, i32* %op0
ld.d $t0, $fp, -24
ld.w $t1, $fp, -165
st.w $t1, $t0, 0
# br label %label41
b .main_label41
main_exit:
addi.d $sp, $sp, 176
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -48
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# store i32 2, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 2
st.w $t1, $t0, 0
# %op1 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -32
# %op2 = icmp ne i32 %op1, 0
ld.w $t0, $fp, -32
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -33
# br i1 %op2, label %label3, label %label4
ld.b $t0, $fp, -33
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label3
b .main_label4
.main_label3:
# store i32 3, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 3
st.w $t1, $t0, 0
# br label %label4
b .main_label4
.main_label4:
# store i32 4, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 4
st.w $t1, $t0, 0
# ret void
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 48
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -48
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# store i32 10, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 10
st.w $t1, $t0, 0
# br label %label1
b .main_label1
.main_label1:
# %op2 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -32
# %op3 = icmp ne i32 %op2, 0
ld.w $t0, $fp, -32
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -33
# br i1 %op3, label %label4, label %label7
ld.b $t0, $fp, -33
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label4
b .main_label7
.main_label4:
# %op5 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -37
# %op6 = sub i32 %op5, 1
ld.w $t0, $fp, -37
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -41
# store i32 %op6, i32* %op0
ld.d $t0, $fp, -24
ld.w $t1, $fp, -41
st.w $t1, $t0, 0
# br label %label1
b .main_label1
.main_label7:
# ret void
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 48
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -112
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = alloca i32
addi.d $t0, $fp, -40
st.d $t0, $fp, -36
# %op2 = alloca i32
addi.d $t0, $fp, -52
st.d $t0, $fp, -48
# store i32 0, i32* %op1
ld.d $t0, $fp, -36
addi.w $t1, $zero, 0
st.w $t1, $t0, 0
# store i32 0, i32* %op2
ld.d $t0, $fp, -48
addi.w $t1, $zero, 0
st.w $t1, $t0, 0
# store i32 10, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 10
st.w $t1, $t0, 0
# br label %label3
b .main_label3
.main_label3:
# %op4 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -56
# %op5 = icmp ne i32 %op4, 0
ld.w $t0, $fp, -56
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -57
# br i1 %op5, label %label6, label %label13
ld.b $t0, $fp, -57
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label6
b .main_label13
.main_label6:
# %op7 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -61
# %op8 = sub i32 %op7, 1
ld.w $t0, $fp, -61
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -65
# store i32 %op8, i32* %op0
ld.d $t0, $fp, -24
ld.w $t1, $fp, -65
st.w $t1, $t0, 0
# %op9 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -69
# %op10 = icmp slt i32 %op9, 5
ld.w $t0, $fp, -69
addi.w $t1, $zero, 5
slt $t2, $t0, $t1
st.b $t2, $fp, -70
# %op11 = zext i1 %op10 to i32
ld.b $t0, $fp, -70
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -74
# %op12 = icmp ne i32 %op11, 0
ld.w $t0, $fp, -74
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -75
# br i1 %op12, label %label17, label %label22
ld.b $t0, $fp, -75
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label17
b .main_label22
.main_label13:
# %op14 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -79
# %op15 = load i32, i32* %op2
ld.d $t0, $fp, -48
ld.w $t0, $t0, 0
st.w $t0, $fp, -83
# %op16 = add i32 %op14, %op15
ld.w $t0, $fp, -79
ld.w $t1, $fp, -83
add.w $t2, $t0, $t1
st.w $t2, $fp, -87
# ret i32 %op16
ld.w $a0, $fp, -87
b main_exit
.main_label17:
# %op18 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -91
# %op19 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -95
# %op20 = add i32 %op18, %op19
ld.w $t0, $fp, -91
ld.w $t1, $fp, -95
add.w $t2, $t0, $t1
st.w $t2, $fp, -99
# store i32 %op20, i32* %op1
ld.d $t0, $fp, -36
ld.w $t1, $fp, -99
st.w $t1, $t0, 0
# br label %label21
b .main_label21
.main_label21:
# br label %label3
b .main_label3
.main_label22:
# %op23 = load i32, i32* %op2
ld.d $t0, $fp, -48
ld.w $t0, $t0, 0
st.w $t0, $fp, -103
# %op24 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -107
# %op25 = add i32 %op23, %op24
ld.w $t0, $fp, -103
ld.w $t1, $fp, -107
add.w $t2, $t0, $t1
st.w $t2, $fp, -111
# store i32 %op25, i32* %op2
ld.d $t0, $fp, -48
ld.w $t1, $fp, -111
st.w $t1, $t0, 0
# br label %label21
b .main_label21
main_exit:
addi.d $sp, $sp, 112
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -80
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = alloca i32
addi.d $t0, $fp, -40
st.d $t0, $fp, -36
# %op2 = alloca i32
addi.d $t0, $fp, -52
st.d $t0, $fp, -48
# store i32 0, i32* %op2
ld.d $t0, $fp, -48
addi.w $t1, $zero, 0
st.w $t1, $t0, 0
# store i32 2, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 2
st.w $t1, $t0, 0
# store i32 1, i32* %op1
ld.d $t0, $fp, -36
addi.w $t1, $zero, 1
st.w $t1, $t0, 0
# %op3 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -56
# %op4 = icmp ne i32 %op3, 0
ld.w $t0, $fp, -56
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -57
# br i1 %op4, label %label5, label %label8
ld.b $t0, $fp, -57
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label5
b .main_label8
.main_label5:
# %op6 = load i32, i32* %op2
ld.d $t0, $fp, -48
ld.w $t0, $t0, 0
st.w $t0, $fp, -61
# %op7 = icmp ne i32 %op6, 0
ld.w $t0, $fp, -61
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -62
# br i1 %op7, label %label10, label %label12
ld.b $t0, $fp, -62
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label10
b .main_label12
.main_label8:
# %op9 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -66
# ret i32 %op9
ld.w $a0, $fp, -66
b main_exit
.main_label10:
# store i32 4, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 4
st.w $t1, $t0, 0
# br label %label11
b .main_label11
.main_label11:
# br label %label8
b .main_label8
.main_label12:
# store i32 3, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 3
st.w $t1, $t0, 0
# br label %label11
b .main_label11
main_exit:
addi.d $sp, $sp, 80
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -96
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = alloca i32
addi.d $t0, $fp, -40
st.d $t0, $fp, -36
# store i32 10, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 10
st.w $t1, $t0, 0
# br label %label2
b .main_label2
.main_label2:
# %op3 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -44
# %op4 = icmp ne i32 %op3, 0
ld.w $t0, $fp, -44
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -45
# br i1 %op4, label %label5, label %label9
ld.b $t0, $fp, -45
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label5
b .main_label9
.main_label5:
# %op6 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -49
# %op7 = sub i32 %op6, 1
ld.w $t0, $fp, -49
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -53
# store i32 %op7, i32* %op0
ld.d $t0, $fp, -24
ld.w $t1, $fp, -53
st.w $t1, $t0, 0
# %op8 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -57
# store i32 %op8, i32* %op1
ld.d $t0, $fp, -36
ld.w $t1, $fp, -57
st.w $t1, $t0, 0
# br label %label13
b .main_label13
.main_label9:
# %op10 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -61
# %op11 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -65
# %op12 = add i32 %op10, %op11
ld.w $t0, $fp, -61
ld.w $t1, $fp, -65
add.w $t2, $t0, $t1
st.w $t2, $fp, -69
# ret i32 %op12
ld.w $a0, $fp, -69
b main_exit
.main_label13:
# %op14 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -73
# %op15 = icmp ne i32 %op14, 0
ld.w $t0, $fp, -73
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -74
# br i1 %op15, label %label16, label %label19
ld.b $t0, $fp, -74
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label16
b .main_label19
.main_label16:
# %op17 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -78
# %op18 = sub i32 %op17, 1
ld.w $t0, $fp, -78
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -82
# store i32 %op18, i32* %op1
ld.d $t0, $fp, -36
ld.w $t1, $fp, -82
st.w $t1, $t0, 0
# br label %label13
b .main_label13
.main_label19:
# br label %label2
b .main_label2
main_exit:
addi.d $sp, $sp, 96
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
# Global variables
.text
.section .bss, "aw", @nobits
.globl a
.type a, @object
.size a, 4
a:
.space 4
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -32
.main_label_entry:
# store i32 10, i32* @a
la.local $t0, a
addi.w $t1, $zero, 10
st.w $t1, $t0, 0
# %op0 = load i32, i32* @a
la.local $t0, a
ld.w $t0, $t0, 0
st.w $t0, $fp, -20
# ret i32 %op0
ld.w $a0, $fp, -20
b main_exit
main_exit:
addi.d $sp, $sp, 32
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
# Global variables
.text
.section .bss, "aw", @nobits
.globl a
.type a, @object
.size a, 4
a:
.space 4
.text
.globl GlobalAssign
.type GlobalAssign, @function
GlobalAssign:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -16
.GlobalAssign_label_entry:
# store i32 10, i32* @a
la.local $t0, a
addi.w $t1, $zero, 10
st.w $t1, $t0, 0
# ret void
addi.w $a0, $zero, 0
b GlobalAssign_exit
GlobalAssign_exit:
addi.d $sp, $sp, 16
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -32
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# call void @GlobalAssign()
bl GlobalAssign
# store i32 20, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 20
st.w $t1, $t0, 0
# %op1 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -32
# ret i32 %op1
ld.w $a0, $fp, -32
b main_exit
main_exit:
addi.d $sp, $sp, 32
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/2-calculate.cminus"
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define i32 @main() {
label_entry:
%op0 = alloca i32
%op1 = alloca i32
%op2 = alloca i32
store i32 23, i32* %op0
store i32 25, i32* %op1
store i32 4, i32* %op2
%op3 = load i32, i32* %op0
%op4 = load i32, i32* %op1
%op5 = load i32, i32* %op2
%op6 = mul i32 %op4, %op5
%op7 = add i32 %op3, %op6
ret i32 %op7
}
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -80
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = alloca i32
addi.d $t0, $fp, -40
st.d $t0, $fp, -36
# %op2 = alloca i32
addi.d $t0, $fp, -52
st.d $t0, $fp, -48
# store i32 23, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 23
st.w $t1, $t0, 0
# store i32 25, i32* %op1
ld.d $t0, $fp, -36
addi.w $t1, $zero, 25
st.w $t1, $t0, 0
# store i32 4, i32* %op2
ld.d $t0, $fp, -48
addi.w $t1, $zero, 4
st.w $t1, $t0, 0
# %op3 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -56
# %op4 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -60
# %op5 = load i32, i32* %op2
ld.d $t0, $fp, -48
ld.w $t0, $t0, 0
st.w $t0, $fp, -64
# %op6 = mul i32 %op4, %op5
ld.w $t0, $fp, -60
ld.w $t1, $fp, -64
mul.w $t2, $t0, $t1
st.w $t2, $fp, -68
# %op7 = add i32 %op3, %op6
ld.w $t0, $fp, -56
ld.w $t1, $fp, -68
add.w $t2, $t0, $t1
st.w $t2, $fp, -72
# ret i32 %op7
ld.w $a0, $fp, -72
b main_exit
main_exit:
addi.d $sp, $sp, 80
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -32
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# ret void
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 32
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
# Global variables
.text
.section .bss, "aw", @nobits
.globl x
.type x, @object
.size x, 4
x:
.space 4
.globl y
.type y, @object
.size y, 4
y:
.space 4
.text
.globl gcd
.type gcd, @function
gcd:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -112
st.w $a0, $fp, -20
st.w $a1, $fp, -24
.gcd_label_entry:
# %op2 = alloca i32
addi.d $t0, $fp, -36
st.d $t0, $fp, -32
# store i32 %arg0, i32* %op2
ld.d $t0, $fp, -32
ld.w $t1, $fp, -20
st.w $t1, $t0, 0
# %op3 = alloca i32
addi.d $t0, $fp, -48
st.d $t0, $fp, -44
# store i32 %arg1, i32* %op3
ld.d $t0, $fp, -44
ld.w $t1, $fp, -24
st.w $t1, $t0, 0
# %op4 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -52
# %op5 = icmp eq i32 %op4, 0
ld.w $t0, $fp, -52
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltui $t2, $t2, 1
st.b $t2, $fp, -53
# %op6 = zext i1 %op5 to i32
ld.b $t0, $fp, -53
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -57
# %op7 = icmp ne i32 %op6, 0
ld.w $t0, $fp, -57
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -58
# br i1 %op7, label %label8, label %label11
ld.b $t0, $fp, -58
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .gcd_label8
b .gcd_label11
.gcd_label8:
# %op9 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -62
# ret i32 %op9
ld.w $a0, $fp, -62
b gcd_exit
.gcd_label10:
# ret i32 0
addi.w $a0, $zero, 0
b gcd_exit
.gcd_label11:
# %op12 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -66
# %op13 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -70
# %op14 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -74
# %op15 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -78
# %op16 = sdiv i32 %op14, %op15
ld.w $t0, $fp, -74
ld.w $t1, $fp, -78
div.w $t2, $t0, $t1
st.w $t2, $fp, -82
# %op17 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -86
# %op18 = mul i32 %op16, %op17
ld.w $t0, $fp, -82
ld.w $t1, $fp, -86
mul.w $t2, $t0, $t1
st.w $t2, $fp, -90
# %op19 = sub i32 %op13, %op18
ld.w $t0, $fp, -70
ld.w $t1, $fp, -90
sub.w $t2, $t0, $t1
st.w $t2, $fp, -94
# %op20 = call i32 @gcd(i32 %op12, i32 %op19)
ld.w $a0, $fp, -66
ld.w $a1, $fp, -94
bl gcd
st.w $a0, $fp, -98
# ret i32 %op20
ld.w $a0, $fp, -98
b gcd_exit
gcd_exit:
addi.d $sp, $sp, 112
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl funArray
.type funArray, @function
funArray:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -192
st.d $a0, $fp, -24
st.d $a1, $fp, -32
.funArray_label_entry:
# %op2 = alloca i32*
addi.d $t0, $fp, -48
st.d $t0, $fp, -40
# store i32* %arg0, i32** %op2
ld.d $t0, $fp, -40
ld.d $t1, $fp, -24
st.d $t1, $t0, 0
# %op3 = alloca i32*
addi.d $t0, $fp, -64
st.d $t0, $fp, -56
# store i32* %arg1, i32** %op3
ld.d $t0, $fp, -56
ld.d $t1, $fp, -32
st.d $t1, $t0, 0
# %op4 = alloca i32
addi.d $t0, $fp, -76
st.d $t0, $fp, -72
# %op5 = alloca i32
addi.d $t0, $fp, -88
st.d $t0, $fp, -84
# %op6 = alloca i32
addi.d $t0, $fp, -100
st.d $t0, $fp, -96
# %op7 = icmp slt i32 0, 0
addi.w $t0, $zero, 0
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -101
# br i1 %op7, label %label8, label %label9
ld.b $t0, $fp, -101
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .funArray_label8
b .funArray_label9
.funArray_label8:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b funArray_exit
.funArray_label9:
# %op10 = load i32*, i32** %op2
ld.d $t0, $fp, -40
ld.d $t0, $t0, 0
st.d $t0, $fp, -109
# %op11 = getelementptr i32, i32* %op10, i32 0
ld.d $t0, $fp, -109
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -117
# %op12 = load i32, i32* %op11
ld.d $t0, $fp, -117
ld.w $t0, $t0, 0
st.w $t0, $fp, -121
# store i32 %op12, i32* %op4
ld.d $t0, $fp, -72
ld.w $t1, $fp, -121
st.w $t1, $t0, 0
# %op13 = icmp slt i32 0, 0
addi.w $t0, $zero, 0
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -122
# br i1 %op13, label %label14, label %label15
ld.b $t0, $fp, -122
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .funArray_label14
b .funArray_label15
.funArray_label14:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b funArray_exit
.funArray_label15:
# %op16 = load i32*, i32** %op3
ld.d $t0, $fp, -56
ld.d $t0, $t0, 0
st.d $t0, $fp, -130
# %op17 = getelementptr i32, i32* %op16, i32 0
ld.d $t0, $fp, -130
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -138
# %op18 = load i32, i32* %op17
ld.d $t0, $fp, -138
ld.w $t0, $t0, 0
st.w $t0, $fp, -142
# store i32 %op18, i32* %op5
ld.d $t0, $fp, -84
ld.w $t1, $fp, -142
st.w $t1, $t0, 0
# %op19 = load i32, i32* %op4
ld.d $t0, $fp, -72
ld.w $t0, $t0, 0
st.w $t0, $fp, -146
# %op20 = load i32, i32* %op5
ld.d $t0, $fp, -84
ld.w $t0, $t0, 0
st.w $t0, $fp, -150
# %op21 = icmp slt i32 %op19, %op20
ld.w $t0, $fp, -146
ld.w $t1, $fp, -150
slt $t2, $t0, $t1
st.b $t2, $fp, -151
# %op22 = zext i1 %op21 to i32
ld.b $t0, $fp, -151
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -155
# %op23 = icmp ne i32 %op22, 0
ld.w $t0, $fp, -155
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -156
# br i1 %op23, label %label24, label %label28
ld.b $t0, $fp, -156
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .funArray_label24
b .funArray_label28
.funArray_label24:
# %op25 = load i32, i32* %op4
ld.d $t0, $fp, -72
ld.w $t0, $t0, 0
st.w $t0, $fp, -160
# store i32 %op25, i32* %op6
ld.d $t0, $fp, -96
ld.w $t1, $fp, -160
st.w $t1, $t0, 0
# %op26 = load i32, i32* %op5
ld.d $t0, $fp, -84
ld.w $t0, $t0, 0
st.w $t0, $fp, -164
# store i32 %op26, i32* %op4
ld.d $t0, $fp, -72
ld.w $t1, $fp, -164
st.w $t1, $t0, 0
# %op27 = load i32, i32* %op6
ld.d $t0, $fp, -96
ld.w $t0, $t0, 0
st.w $t0, $fp, -168
# store i32 %op27, i32* %op5
ld.d $t0, $fp, -84
ld.w $t1, $fp, -168
st.w $t1, $t0, 0
# br label %label28
b .funArray_label28
.funArray_label28:
# %op29 = load i32, i32* %op4
ld.d $t0, $fp, -72
ld.w $t0, $t0, 0
st.w $t0, $fp, -172
# %op30 = load i32, i32* %op5
ld.d $t0, $fp, -84
ld.w $t0, $t0, 0
st.w $t0, $fp, -176
# %op31 = call i32 @gcd(i32 %op29, i32 %op30)
ld.w $a0, $fp, -172
ld.w $a1, $fp, -176
bl gcd
st.w $a0, $fp, -180
# ret i32 %op31
ld.w $a0, $fp, -180
b funArray_exit
funArray_exit:
addi.d $sp, $sp, 192
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -64
.main_label_entry:
# %op0 = icmp slt i32 0, 0
addi.w $t0, $zero, 0
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -17
# br i1 %op0, label %label1, label %label2
ld.b $t0, $fp, -17
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label1
b .main_label2
.main_label1:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label2:
# %op3 = getelementptr [1 x i32], [1 x i32]* @x, i32 0, i32 0
la.local $t0, x
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -25
# store i32 90, i32* %op3
ld.d $t0, $fp, -25
addi.w $t1, $zero, 90
st.w $t1, $t0, 0
# %op4 = icmp slt i32 0, 0
addi.w $t0, $zero, 0
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -26
# br i1 %op4, label %label5, label %label6
ld.b $t0, $fp, -26
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label5
b .main_label6
.main_label5:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label6:
# %op7 = getelementptr [1 x i32], [1 x i32]* @y, i32 0, i32 0
la.local $t0, y
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -34
# store i32 18, i32* %op7
ld.d $t0, $fp, -34
addi.w $t1, $zero, 18
st.w $t1, $t0, 0
# %op8 = getelementptr [1 x i32], [1 x i32]* @x, i32 0, i32 0
la.local $t0, x
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -42
# %op9 = getelementptr [1 x i32], [1 x i32]* @y, i32 0, i32 0
la.local $t0, y
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -50
# %op10 = call i32 @funArray(i32* %op8, i32* %op9)
ld.d $a0, $fp, -42
ld.d $a1, $fp, -50
bl funArray
st.w $a0, $fp, -54
# ret i32 %op10
ld.w $a0, $fp, -54
b main_exit
main_exit:
addi.d $sp, $sp, 64
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -16
.main_label_entry:
# ret void
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 16
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -32
.main_label_entry:
# %op0 = alloca float
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# ret void
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 32
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/3-output.cminus"
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define i32 @main() {
label_entry:
call void @output(i32 11)
call void @output(i32 22222)
ret i32 0
}
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -16
.main_label_entry:
# call void @output(i32 11)
addi.w $a0, $zero, 11
bl output
# call void @output(i32 22222)
lu12i.w $a0, 5
ori $a0, $a0, 1742
bl output
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 16
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -64
.main_label_entry:
# %op0 = alloca [10 x i32]
addi.d $t0, $fp, -64
st.d $t0, $fp, -24
# ret void
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 64
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/4-if.cminus"
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define i32 @main() {
label_entry:
%op0 = alloca i32
%op1 = alloca i32
%op2 = alloca i32
store i32 11, i32* %op0
store i32 22, i32* %op1
store i32 33, i32* %op2
%op3 = load i32, i32* %op0
%op4 = load i32, i32* %op1
%op5 = icmp sgt i32 %op3, %op4
%op6 = zext i1 %op5 to i32
%op7 = icmp ne i32 %op6, 0
br i1 %op7, label %label8, label %label15
label8: ; preds = %label_entry
%op9 = load i32, i32* %op0
%op10 = load i32, i32* %op2
%op11 = icmp sgt i32 %op9, %op10
%op12 = zext i1 %op11 to i32
%op13 = icmp ne i32 %op12, 0
br i1 %op13, label %label21, label %label24
label14: ; preds = %label23, %label28
ret i32 0
label15: ; preds = %label_entry
%op16 = load i32, i32* %op2
%op17 = load i32, i32* %op1
%op18 = icmp slt i32 %op16, %op17
%op19 = zext i1 %op18 to i32
%op20 = icmp ne i32 %op19, 0
br i1 %op20, label %label26, label %label29
label21: ; preds = %label8
%op22 = load i32, i32* %op0
call void @output(i32 %op22)
br label %label23
label23: ; preds = %label21, %label24
br label %label14
label24: ; preds = %label8
%op25 = load i32, i32* %op2
call void @output(i32 %op25)
br label %label23
label26: ; preds = %label15
%op27 = load i32, i32* %op1
call void @output(i32 %op27)
br label %label28
label28: ; preds = %label26, %label29
br label %label14
label29: ; preds = %label15
%op30 = load i32, i32* %op2
call void @output(i32 %op30)
br label %label28
}
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -112
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = alloca i32
addi.d $t0, $fp, -40
st.d $t0, $fp, -36
# %op2 = alloca i32
addi.d $t0, $fp, -52
st.d $t0, $fp, -48
# store i32 11, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 11
st.w $t1, $t0, 0
# store i32 22, i32* %op1
ld.d $t0, $fp, -36
addi.w $t1, $zero, 22
st.w $t1, $t0, 0
# store i32 33, i32* %op2
ld.d $t0, $fp, -48
addi.w $t1, $zero, 33
st.w $t1, $t0, 0
# %op3 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -56
# %op4 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -60
# %op5 = icmp sgt i32 %op3, %op4
ld.w $t0, $fp, -56
ld.w $t1, $fp, -60
slt $t2, $t1, $t0
st.b $t2, $fp, -61
# %op6 = zext i1 %op5 to i32
ld.b $t0, $fp, -61
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -65
# %op7 = icmp ne i32 %op6, 0
ld.w $t0, $fp, -65
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -66
# br i1 %op7, label %label8, label %label15
ld.b $t0, $fp, -66
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label8
b .main_label15
.main_label8:
# %op9 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -70
# %op10 = load i32, i32* %op2
ld.d $t0, $fp, -48
ld.w $t0, $t0, 0
st.w $t0, $fp, -74
# %op11 = icmp sgt i32 %op9, %op10
ld.w $t0, $fp, -70
ld.w $t1, $fp, -74
slt $t2, $t1, $t0
st.b $t2, $fp, -75
# %op12 = zext i1 %op11 to i32
ld.b $t0, $fp, -75
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -79
# %op13 = icmp ne i32 %op12, 0
ld.w $t0, $fp, -79
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -80
# br i1 %op13, label %label21, label %label24
ld.b $t0, $fp, -80
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label21
b .main_label24
.main_label14:
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label15:
# %op16 = load i32, i32* %op2
ld.d $t0, $fp, -48
ld.w $t0, $t0, 0
st.w $t0, $fp, -84
# %op17 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -88
# %op18 = icmp slt i32 %op16, %op17
ld.w $t0, $fp, -84
ld.w $t1, $fp, -88
slt $t2, $t0, $t1
st.b $t2, $fp, -89
# %op19 = zext i1 %op18 to i32
ld.b $t0, $fp, -89
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -93
# %op20 = icmp ne i32 %op19, 0
ld.w $t0, $fp, -93
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -94
# br i1 %op20, label %label26, label %label29
ld.b $t0, $fp, -94
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label26
b .main_label29
.main_label21:
# %op22 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -98
# call void @output(i32 %op22)
ld.w $a0, $fp, -98
bl output
# br label %label23
b .main_label23
.main_label23:
# br label %label14
b .main_label14
.main_label24:
# %op25 = load i32, i32* %op2
ld.d $t0, $fp, -48
ld.w $t0, $t0, 0
st.w $t0, $fp, -102
# call void @output(i32 %op25)
ld.w $a0, $fp, -102
bl output
# br label %label23
b .main_label23
.main_label26:
# %op27 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -106
# call void @output(i32 %op27)
ld.w $a0, $fp, -106
bl output
# br label %label28
b .main_label28
.main_label28:
# br label %label14
b .main_label14
.main_label29:
# %op30 = load i32, i32* %op2
ld.d $t0, $fp, -48
ld.w $t0, $t0, 0
st.w $t0, $fp, -110
# call void @output(i32 %op30)
ld.w $a0, $fp, -110
bl output
# br label %label28
b .main_label28
main_exit:
addi.d $sp, $sp, 112
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -64
.main_label_entry:
# %op0 = alloca [10 x float]
addi.d $t0, $fp, -64
st.d $t0, $fp, -24
# ret void
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 64
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/5-while.cminus"
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define i32 @main() {
label_entry:
%op0 = alloca i32
%op1 = alloca i32
store i32 10, i32* %op0
store i32 0, i32* %op1
br label %label2
label2: ; preds = %label_entry, %label8
%op3 = load i32, i32* %op1
%op4 = load i32, i32* %op0
%op5 = icmp slt i32 %op3, %op4
%op6 = zext i1 %op5 to i32
%op7 = icmp ne i32 %op6, 0
br i1 %op7, label %label8, label %label12
label8: ; preds = %label2
%op9 = load i32, i32* %op1
call void @output(i32 %op9)
%op10 = load i32, i32* %op1
%op11 = add i32 %op10, 1
store i32 %op11, i32* %op1
br label %label2
label12: ; preds = %label2
ret i32 0
}
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -80
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = alloca i32
addi.d $t0, $fp, -40
st.d $t0, $fp, -36
# store i32 10, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 10
st.w $t1, $t0, 0
# store i32 0, i32* %op1
ld.d $t0, $fp, -36
addi.w $t1, $zero, 0
st.w $t1, $t0, 0
# br label %label2
b .main_label2
.main_label2:
# %op3 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -44
# %op4 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -48
# %op5 = icmp slt i32 %op3, %op4
ld.w $t0, $fp, -44
ld.w $t1, $fp, -48
slt $t2, $t0, $t1
st.b $t2, $fp, -49
# %op6 = zext i1 %op5 to i32
ld.b $t0, $fp, -49
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -53
# %op7 = icmp ne i32 %op6, 0
ld.w $t0, $fp, -53
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -54
# br i1 %op7, label %label8, label %label12
ld.b $t0, $fp, -54
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label8
b .main_label12
.main_label8:
# %op9 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -58
# call void @output(i32 %op9)
ld.w $a0, $fp, -58
bl output
# %op10 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -62
# %op11 = add i32 %op10, 1
ld.w $t0, $fp, -62
addi.w $t1, $zero, 1
add.w $t2, $t0, $t1
st.w $t2, $fp, -66
# store i32 %op11, i32* %op1
ld.d $t0, $fp, -36
ld.w $t1, $fp, -66
st.w $t1, $t0, 0
# br label %label2
b .main_label2
.main_label12:
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 80
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/6-array.cminus"
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define i32 @main() {
label_entry:
%op0 = alloca [10 x i32]
%op1 = alloca i32
store i32 0, i32* %op1
%op2 = icmp slt i32 0, 0
br i1 %op2, label %label3, label %label4
label3: ; preds = %label_entry
call void @neg_idx_except()
ret i32 0
label4: ; preds = %label_entry
%op5 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 0
store i32 11, i32* %op5
%op6 = icmp slt i32 4, 0
br i1 %op6, label %label7, label %label8
label7: ; preds = %label4
call void @neg_idx_except()
ret i32 0
label8: ; preds = %label4
%op9 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 4
store i32 22, i32* %op9
%op10 = icmp slt i32 9, 0
br i1 %op10, label %label11, label %label12
label11: ; preds = %label8
call void @neg_idx_except()
ret i32 0
label12: ; preds = %label8
%op13 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 9
store i32 33, i32* %op13
%op14 = icmp slt i32 0, 0
br i1 %op14, label %label15, label %label16
label15: ; preds = %label12
call void @neg_idx_except()
ret i32 0
label16: ; preds = %label12
%op17 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 0
%op18 = load i32, i32* %op17
call void @output(i32 %op18)
%op19 = icmp slt i32 4, 0
br i1 %op19, label %label20, label %label21
label20: ; preds = %label16
call void @neg_idx_except()
ret i32 0
label21: ; preds = %label16
%op22 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 4
%op23 = load i32, i32* %op22
call void @output(i32 %op23)
%op24 = icmp slt i32 9, 0
br i1 %op24, label %label25, label %label26
label25: ; preds = %label21
call void @neg_idx_except()
ret i32 0
label26: ; preds = %label21
%op27 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 9
%op28 = load i32, i32* %op27
call void @output(i32 %op28)
ret i32 0
}
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -144
.main_label_entry:
# %op0 = alloca [10 x i32]
addi.d $t0, $fp, -64
st.d $t0, $fp, -24
# %op1 = alloca i32
addi.d $t0, $fp, -76
st.d $t0, $fp, -72
# store i32 0, i32* %op1
ld.d $t0, $fp, -72
addi.w $t1, $zero, 0
st.w $t1, $t0, 0
# %op2 = icmp slt i32 0, 0
addi.w $t0, $zero, 0
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -77
# br i1 %op2, label %label3, label %label4
ld.b $t0, $fp, -77
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label3
b .main_label4
.main_label3:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label4:
# %op5 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 0
addi.d $t2, $zero, 40
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -85
# store i32 11, i32* %op5
ld.d $t0, $fp, -85
addi.w $t1, $zero, 11
st.w $t1, $t0, 0
# %op6 = icmp slt i32 4, 0
addi.w $t0, $zero, 4
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -86
# br i1 %op6, label %label7, label %label8
ld.b $t0, $fp, -86
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label7
b .main_label8
.main_label7:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label8:
# %op9 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 4
ld.d $t0, $fp, -24
addi.w $t1, $zero, 0
addi.d $t2, $zero, 40
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 4
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -94
# store i32 22, i32* %op9
ld.d $t0, $fp, -94
addi.w $t1, $zero, 22
st.w $t1, $t0, 0
# %op10 = icmp slt i32 9, 0
addi.w $t0, $zero, 9
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -95
# br i1 %op10, label %label11, label %label12
ld.b $t0, $fp, -95
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label11
b .main_label12
.main_label11:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label12:
# %op13 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 9
ld.d $t0, $fp, -24
addi.w $t1, $zero, 0
addi.d $t2, $zero, 40
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 9
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -103
# store i32 33, i32* %op13
ld.d $t0, $fp, -103
addi.w $t1, $zero, 33
st.w $t1, $t0, 0
# %op14 = icmp slt i32 0, 0
addi.w $t0, $zero, 0
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -104
# br i1 %op14, label %label15, label %label16
ld.b $t0, $fp, -104
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label15
b .main_label16
.main_label15:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label16:
# %op17 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 0
addi.d $t2, $zero, 40
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -112
# %op18 = load i32, i32* %op17
ld.d $t0, $fp, -112
ld.w $t0, $t0, 0
st.w $t0, $fp, -116
# call void @output(i32 %op18)
ld.w $a0, $fp, -116
bl output
# %op19 = icmp slt i32 4, 0
addi.w $t0, $zero, 4
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -117
# br i1 %op19, label %label20, label %label21
ld.b $t0, $fp, -117
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label20
b .main_label21
.main_label20:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label21:
# %op22 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 4
ld.d $t0, $fp, -24
addi.w $t1, $zero, 0
addi.d $t2, $zero, 40
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 4
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -125
# %op23 = load i32, i32* %op22
ld.d $t0, $fp, -125
ld.w $t0, $t0, 0
st.w $t0, $fp, -129
# call void @output(i32 %op23)
ld.w $a0, $fp, -129
bl output
# %op24 = icmp slt i32 9, 0
addi.w $t0, $zero, 9
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -130
# br i1 %op24, label %label25, label %label26
ld.b $t0, $fp, -130
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label25
b .main_label26
.main_label25:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label26:
# %op27 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 9
ld.d $t0, $fp, -24
addi.w $t1, $zero, 0
addi.d $t2, $zero, 40
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 9
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -138
# %op28 = load i32, i32* %op27
ld.d $t0, $fp, -138
ld.w $t0, $t0, 0
st.w $t0, $fp, -142
# call void @output(i32 %op28)
ld.w $a0, $fp, -142
bl output
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 144
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -48
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = add i32 1000, 234
addi.w $t0, $zero, 1000
addi.w $t1, $zero, 234
add.w $t2, $t0, $t1
st.w $t2, $fp, -32
# store i32 %op1, i32* %op0
ld.d $t0, $fp, -24
ld.w $t1, $fp, -32
st.w $t1, $t0, 0
# %op2 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -36
# ret i32 %op2
ld.w $a0, $fp, -36
b main_exit
main_exit:
addi.d $sp, $sp, 48
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -32
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# store i32 1234, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 1234
st.w $t1, $t0, 0
# %op1 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -32
# ret i32 %op1
ld.w $a0, $fp, -32
b main_exit
main_exit:
addi.d $sp, $sp, 32
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/7-function.cminus"
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define i32 @min(i32 %arg0, i32 %arg1) {
label_entry:
%op2 = alloca i32
store i32 %arg0, i32* %op2
%op3 = alloca i32
store i32 %arg1, i32* %op3
%op4 = load i32, i32* %op2
%op5 = load i32, i32* %op3
%op6 = icmp sle i32 %op4, %op5
%op7 = zext i1 %op6 to i32
%op8 = icmp ne i32 %op7, 0
br i1 %op8, label %label9, label %label12
label9: ; preds = %label_entry
%op10 = load i32, i32* %op2
ret i32 %op10
label11:
ret i32 0
label12: ; preds = %label_entry
%op13 = load i32, i32* %op3
ret i32 %op13
}
define i32 @main() {
label_entry:
%op0 = alloca i32
%op1 = alloca i32
%op2 = alloca i32
store i32 11, i32* %op0
store i32 22, i32* %op1
store i32 33, i32* %op2
%op3 = load i32, i32* %op0
%op4 = load i32, i32* %op1
%op5 = call i32 @min(i32 %op3, i32 %op4)
call void @output(i32 %op5)
%op6 = load i32, i32* %op1
%op7 = load i32, i32* %op2
%op8 = call i32 @min(i32 %op6, i32 %op7)
call void @output(i32 %op8)
%op9 = load i32, i32* %op2
%op10 = load i32, i32* %op0
%op11 = call i32 @min(i32 %op9, i32 %op10)
call void @output(i32 %op11)
ret i32 0
}
.text
.globl min
.type min, @function
min:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -80
st.w $a0, $fp, -20
st.w $a1, $fp, -24
.min_label_entry:
# %op2 = alloca i32
addi.d $t0, $fp, -36
st.d $t0, $fp, -32
# store i32 %arg0, i32* %op2
ld.d $t0, $fp, -32
ld.w $t1, $fp, -20
st.w $t1, $t0, 0
# %op3 = alloca i32
addi.d $t0, $fp, -48
st.d $t0, $fp, -44
# store i32 %arg1, i32* %op3
ld.d $t0, $fp, -44
ld.w $t1, $fp, -24
st.w $t1, $t0, 0
# %op4 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -52
# %op5 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -56
# %op6 = icmp sle i32 %op4, %op5
ld.w $t0, $fp, -52
ld.w $t1, $fp, -56
slt $t2, $t1, $t0
xori $t2, $t2, 1
st.b $t2, $fp, -57
# %op7 = zext i1 %op6 to i32
ld.b $t0, $fp, -57
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -61
# %op8 = icmp ne i32 %op7, 0
ld.w $t0, $fp, -61
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -62
# br i1 %op8, label %label9, label %label12
ld.b $t0, $fp, -62
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .min_label9
b .min_label12
.min_label9:
# %op10 = load i32, i32* %op2
ld.d $t0, $fp, -32
ld.w $t0, $t0, 0
st.w $t0, $fp, -66
# ret i32 %op10
ld.w $a0, $fp, -66
b min_exit
.min_label11:
# ret i32 0
addi.w $a0, $zero, 0
b min_exit
.min_label12:
# %op13 = load i32, i32* %op3
ld.d $t0, $fp, -44
ld.w $t0, $t0, 0
st.w $t0, $fp, -70
# ret i32 %op13
ld.w $a0, $fp, -70
b min_exit
min_exit:
addi.d $sp, $sp, 80
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -96
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = alloca i32
addi.d $t0, $fp, -40
st.d $t0, $fp, -36
# %op2 = alloca i32
addi.d $t0, $fp, -52
st.d $t0, $fp, -48
# store i32 11, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 11
st.w $t1, $t0, 0
# store i32 22, i32* %op1
ld.d $t0, $fp, -36
addi.w $t1, $zero, 22
st.w $t1, $t0, 0
# store i32 33, i32* %op2
ld.d $t0, $fp, -48
addi.w $t1, $zero, 33
st.w $t1, $t0, 0
# %op3 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -56
# %op4 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -60
# %op5 = call i32 @min(i32 %op3, i32 %op4)
ld.w $a0, $fp, -56
ld.w $a1, $fp, -60
bl min
st.w $a0, $fp, -64
# call void @output(i32 %op5)
ld.w $a0, $fp, -64
bl output
# %op6 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -68
# %op7 = load i32, i32* %op2
ld.d $t0, $fp, -48
ld.w $t0, $t0, 0
st.w $t0, $fp, -72
# %op8 = call i32 @min(i32 %op6, i32 %op7)
ld.w $a0, $fp, -68
ld.w $a1, $fp, -72
bl min
st.w $a0, $fp, -76
# call void @output(i32 %op8)
ld.w $a0, $fp, -76
bl output
# %op9 = load i32, i32* %op2
ld.d $t0, $fp, -48
ld.w $t0, $t0, 0
st.w $t0, $fp, -80
# %op10 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -84
# %op11 = call i32 @min(i32 %op9, i32 %op10)
ld.w $a0, $fp, -80
ld.w $a1, $fp, -84
bl min
st.w $a0, $fp, -88
# call void @output(i32 %op11)
ld.w $a0, $fp, -88
bl output
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 96
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -96
.main_label_entry:
# %op0 = alloca [10 x i32]
addi.d $t0, $fp, -64
st.d $t0, $fp, -24
# %op1 = icmp slt i32 3, 0
addi.w $t0, $zero, 3
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -65
# br i1 %op1, label %label2, label %label3
ld.b $t0, $fp, -65
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label2
b .main_label3
.main_label2:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label3:
# %op4 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 3
ld.d $t0, $fp, -24
addi.w $t1, $zero, 0
addi.d $t2, $zero, 40
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 3
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -73
# store i32 1234, i32* %op4
ld.d $t0, $fp, -73
addi.w $t1, $zero, 1234
st.w $t1, $t0, 0
# %op5 = icmp slt i32 3, 0
addi.w $t0, $zero, 3
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -74
# br i1 %op5, label %label6, label %label7
ld.b $t0, $fp, -74
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label6
b .main_label7
.main_label6:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label7:
# %op8 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 3
ld.d $t0, $fp, -24
addi.w $t1, $zero, 0
addi.d $t2, $zero, 40
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 3
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -82
# %op9 = load i32, i32* %op8
ld.d $t0, $fp, -82
ld.w $t0, $t0, 0
st.w $t0, $fp, -86
# ret i32 %op9
ld.w $a0, $fp, -86
b main_exit
main_exit:
addi.d $sp, $sp, 96
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/8-store.cminus"
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define i32 @store(i32* %arg0, i32 %arg1, i32 %arg2) {
label_entry:
%op3 = alloca i32*
store i32* %arg0, i32** %op3
%op4 = alloca i32
store i32 %arg1, i32* %op4
%op5 = alloca i32
store i32 %arg2, i32* %op5
%op6 = load i32, i32* %op5
%op7 = load i32, i32* %op4
%op8 = icmp slt i32 %op7, 0
br i1 %op8, label %label9, label %label10
label9: ; preds = %label_entry
call void @neg_idx_except()
ret i32 0
label10: ; preds = %label_entry
%op11 = load i32*, i32** %op3
%op12 = getelementptr i32, i32* %op11, i32 %op7
store i32 %op6, i32* %op12
%op13 = load i32, i32* %op5
ret i32 %op13
}
define i32 @main() {
label_entry:
%op0 = alloca [10 x i32]
%op1 = alloca i32
%op2 = alloca i32
store i32 0, i32* %op1
br label %label3
label3: ; preds = %label_entry, %label8
%op4 = load i32, i32* %op1
%op5 = icmp slt i32 %op4, 10
%op6 = zext i1 %op5 to i32
%op7 = icmp ne i32 %op6, 0
br i1 %op7, label %label8, label %label16
label8: ; preds = %label3
%op9 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 0
%op10 = load i32, i32* %op1
%op11 = load i32, i32* %op1
%op12 = mul i32 %op11, 2
%op13 = call i32 @store(i32* %op9, i32 %op10, i32 %op12)
%op14 = load i32, i32* %op1
%op15 = add i32 %op14, 1
store i32 %op15, i32* %op1
br label %label3
label16: ; preds = %label3
store i32 0, i32* %op2
store i32 0, i32* %op1
br label %label17
label17: ; preds = %label16, %label29
%op18 = load i32, i32* %op1
%op19 = icmp slt i32 %op18, 10
%op20 = zext i1 %op19 to i32
%op21 = icmp ne i32 %op20, 0
br i1 %op21, label %label22, label %label26
label22: ; preds = %label17
%op23 = load i32, i32* %op2
%op24 = load i32, i32* %op1
%op25 = icmp slt i32 %op24, 0
br i1 %op25, label %label28, label %label29
label26: ; preds = %label17
%op27 = load i32, i32* %op2
call void @output(i32 %op27)
ret i32 0
label28: ; preds = %label22
call void @neg_idx_except()
ret i32 0
label29: ; preds = %label22
%op30 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 %op24
%op31 = load i32, i32* %op30
%op32 = add i32 %op23, %op31
store i32 %op32, i32* %op2
%op33 = load i32, i32* %op1
%op34 = add i32 %op33, 1
store i32 %op34, i32* %op1
br label %label17
}
.text
.globl store
.type store, @function
store:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -112
st.d $a0, $fp, -24
st.w $a1, $fp, -28
st.w $a2, $fp, -32
.store_label_entry:
# %op3 = alloca i32*
addi.d $t0, $fp, -48
st.d $t0, $fp, -40
# store i32* %arg0, i32** %op3
ld.d $t0, $fp, -40
ld.d $t1, $fp, -24
st.d $t1, $t0, 0
# %op4 = alloca i32
addi.d $t0, $fp, -60
st.d $t0, $fp, -56
# store i32 %arg1, i32* %op4
ld.d $t0, $fp, -56
ld.w $t1, $fp, -28
st.w $t1, $t0, 0
# %op5 = alloca i32
addi.d $t0, $fp, -72
st.d $t0, $fp, -68
# store i32 %arg2, i32* %op5
ld.d $t0, $fp, -68
ld.w $t1, $fp, -32
st.w $t1, $t0, 0
# %op6 = load i32, i32* %op5
ld.d $t0, $fp, -68
ld.w $t0, $t0, 0
st.w $t0, $fp, -76
# %op7 = load i32, i32* %op4
ld.d $t0, $fp, -56
ld.w $t0, $t0, 0
st.w $t0, $fp, -80
# %op8 = icmp slt i32 %op7, 0
ld.w $t0, $fp, -80
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -81
# br i1 %op8, label %label9, label %label10
ld.b $t0, $fp, -81
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .store_label9
b .store_label10
.store_label9:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b store_exit
.store_label10:
# %op11 = load i32*, i32** %op3
ld.d $t0, $fp, -40
ld.d $t0, $t0, 0
st.d $t0, $fp, -89
# %op12 = getelementptr i32, i32* %op11, i32 %op7
ld.d $t0, $fp, -89
ld.w $t1, $fp, -80
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -97
# store i32 %op6, i32* %op12
ld.d $t0, $fp, -97
ld.w $t1, $fp, -76
st.w $t1, $t0, 0
# %op13 = load i32, i32* %op5
ld.d $t0, $fp, -68
ld.w $t0, $t0, 0
st.w $t0, $fp, -101
# ret i32 %op13
ld.w $a0, $fp, -101
b store_exit
store_exit:
addi.d $sp, $sp, 112
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -192
.main_label_entry:
# %op0 = alloca [10 x i32]
addi.d $t0, $fp, -64
st.d $t0, $fp, -24
# %op1 = alloca i32
addi.d $t0, $fp, -76
st.d $t0, $fp, -72
# %op2 = alloca i32
addi.d $t0, $fp, -88
st.d $t0, $fp, -84
# store i32 0, i32* %op1
ld.d $t0, $fp, -72
addi.w $t1, $zero, 0
st.w $t1, $t0, 0
# br label %label3
b .main_label3
.main_label3:
# %op4 = load i32, i32* %op1
ld.d $t0, $fp, -72
ld.w $t0, $t0, 0
st.w $t0, $fp, -92
# %op5 = icmp slt i32 %op4, 10
ld.w $t0, $fp, -92
addi.w $t1, $zero, 10
slt $t2, $t0, $t1
st.b $t2, $fp, -93
# %op6 = zext i1 %op5 to i32
ld.b $t0, $fp, -93
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -97
# %op7 = icmp ne i32 %op6, 0
ld.w $t0, $fp, -97
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -98
# br i1 %op7, label %label8, label %label16
ld.b $t0, $fp, -98
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label8
b .main_label16
.main_label8:
# %op9 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 0
addi.d $t2, $zero, 40
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
addi.w $t1, $zero, 0
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -106
# %op10 = load i32, i32* %op1
ld.d $t0, $fp, -72
ld.w $t0, $t0, 0
st.w $t0, $fp, -110
# %op11 = load i32, i32* %op1
ld.d $t0, $fp, -72
ld.w $t0, $t0, 0
st.w $t0, $fp, -114
# %op12 = mul i32 %op11, 2
ld.w $t0, $fp, -114
addi.w $t1, $zero, 2
mul.w $t2, $t0, $t1
st.w $t2, $fp, -118
# %op13 = call i32 @store(i32* %op9, i32 %op10, i32 %op12)
ld.d $a0, $fp, -106
ld.w $a1, $fp, -110
ld.w $a2, $fp, -118
bl store
st.w $a0, $fp, -122
# %op14 = load i32, i32* %op1
ld.d $t0, $fp, -72
ld.w $t0, $t0, 0
st.w $t0, $fp, -126
# %op15 = add i32 %op14, 1
ld.w $t0, $fp, -126
addi.w $t1, $zero, 1
add.w $t2, $t0, $t1
st.w $t2, $fp, -130
# store i32 %op15, i32* %op1
ld.d $t0, $fp, -72
ld.w $t1, $fp, -130
st.w $t1, $t0, 0
# br label %label3
b .main_label3
.main_label16:
# store i32 0, i32* %op2
ld.d $t0, $fp, -84
addi.w $t1, $zero, 0
st.w $t1, $t0, 0
# store i32 0, i32* %op1
ld.d $t0, $fp, -72
addi.w $t1, $zero, 0
st.w $t1, $t0, 0
# br label %label17
b .main_label17
.main_label17:
# %op18 = load i32, i32* %op1
ld.d $t0, $fp, -72
ld.w $t0, $t0, 0
st.w $t0, $fp, -134
# %op19 = icmp slt i32 %op18, 10
ld.w $t0, $fp, -134
addi.w $t1, $zero, 10
slt $t2, $t0, $t1
st.b $t2, $fp, -135
# %op20 = zext i1 %op19 to i32
ld.b $t0, $fp, -135
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -139
# %op21 = icmp ne i32 %op20, 0
ld.w $t0, $fp, -139
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -140
# br i1 %op21, label %label22, label %label26
ld.b $t0, $fp, -140
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label22
b .main_label26
.main_label22:
# %op23 = load i32, i32* %op2
ld.d $t0, $fp, -84
ld.w $t0, $t0, 0
st.w $t0, $fp, -144
# %op24 = load i32, i32* %op1
ld.d $t0, $fp, -72
ld.w $t0, $t0, 0
st.w $t0, $fp, -148
# %op25 = icmp slt i32 %op24, 0
ld.w $t0, $fp, -148
addi.w $t1, $zero, 0
slt $t2, $t0, $t1
st.b $t2, $fp, -149
# br i1 %op25, label %label28, label %label29
ld.b $t0, $fp, -149
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label28
b .main_label29
.main_label26:
# %op27 = load i32, i32* %op2
ld.d $t0, $fp, -84
ld.w $t0, $t0, 0
st.w $t0, $fp, -153
# call void @output(i32 %op27)
ld.w $a0, $fp, -153
bl output
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label28:
# call void @neg_idx_except()
bl neg_idx_except
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
.main_label29:
# %op30 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 %op24
ld.d $t0, $fp, -24
addi.w $t1, $zero, 0
addi.d $t2, $zero, 40
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
ld.w $t1, $fp, -148
addi.d $t2, $zero, 4
mul.d $t1, $t1, $t2
add.d $t0, $t0, $t1
st.d $t0, $fp, -161
# %op31 = load i32, i32* %op30
ld.d $t0, $fp, -161
ld.w $t0, $t0, 0
st.w $t0, $fp, -165
# %op32 = add i32 %op23, %op31
ld.w $t0, $fp, -144
ld.w $t1, $fp, -165
add.w $t2, $t0, $t1
st.w $t2, $fp, -169
# store i32 %op32, i32* %op2
ld.d $t0, $fp, -84
ld.w $t1, $fp, -169
st.w $t1, $t0, 0
# %op33 = load i32, i32* %op1
ld.d $t0, $fp, -72
ld.w $t0, $t0, 0
st.w $t0, $fp, -173
# %op34 = add i32 %op33, 1
ld.w $t0, $fp, -173
addi.w $t1, $zero, 1
add.w $t2, $t0, $t1
st.w $t2, $fp, -177
# store i32 %op34, i32* %op1
ld.d $t0, $fp, -72
ld.w $t1, $fp, -177
st.w $t1, $t0, 0
# br label %label17
b .main_label17
main_exit:
addi.d $sp, $sp, 192
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.text
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -80
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = alloca i32
addi.d $t0, $fp, -40
st.d $t0, $fp, -36
# %op2 = icmp slt i32 1, 3
addi.w $t0, $zero, 1
addi.w $t1, $zero, 3
slt $t2, $t0, $t1
st.b $t2, $fp, -41
# %op3 = zext i1 %op2 to i32
ld.b $t0, $fp, -41
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -45
# store i32 %op3, i32* %op0
ld.d $t0, $fp, -24
ld.w $t1, $fp, -45
st.w $t1, $t0, 0
# %op4 = sitofp i32 2 to float
addi.w $t0, $zero, 2
movgr2fr.w $ft0, $t0
ffint.s.w $ft0, $ft0
fst.s $ft0, $fp, -49
# %op5 = fadd float %op4, 0x4003333340000000
fld.s $ft0, $fp, -49
lu12i.w $t8, 262553
ori $t8, $t8, 2458
movgr2fr.w $ft1, $t8
fadd.s $ft2, $ft0, $ft1
fst.s $ft2, $fp, -53
# %op6 = fptosi float %op5 to i32
fld.s $ft0, $fp, -53
ftintrz.w.s $ft0, $ft0
movfr2gr.s $t0, $ft0
st.w $t0, $fp, -57
# store i32 %op6, i32* %op1
ld.d $t0, $fp, -36
ld.w $t1, $fp, -57
st.w $t1, $t0, 0
# %op7 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -61
# %op8 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -65
# %op9 = add i32 %op7, %op8
ld.w $t0, $fp, -61
ld.w $t1, $fp, -65
add.w $t2, $t0, $t1
st.w $t2, $fp, -69
# ret i32 %op9
ld.w $a0, $fp, -69
b main_exit
main_exit:
addi.d $sp, $sp, 80
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
; ModuleID = 'cminus'
source_filename = "/code/compiler/24.ta/tests/3-codegen/autogen/testcases/9-fibonacci.cminus"
declare i32 @input()
declare void @output(i32)
declare void @outputFloat(float)
declare void @neg_idx_except()
define i32 @fibonacci(i32 %arg0) {
label_entry:
%op1 = alloca i32
store i32 %arg0, i32* %op1
%op2 = load i32, i32* %op1
%op3 = icmp eq i32 %op2, 0
%op4 = zext i1 %op3 to i32
%op5 = icmp ne i32 %op4, 0
br i1 %op5, label %label6, label %label8
label6: ; preds = %label_entry
ret i32 0
label7: ; preds = %label14
ret i32 0
label8: ; preds = %label_entry
%op9 = load i32, i32* %op1
%op10 = icmp eq i32 %op9, 1
%op11 = zext i1 %op10 to i32
%op12 = icmp ne i32 %op11, 0
br i1 %op12, label %label13, label %label15
label13: ; preds = %label8
ret i32 1
label14:
br label %label7
label15: ; preds = %label8
%op16 = load i32, i32* %op1
%op17 = sub i32 %op16, 1
%op18 = call i32 @fibonacci(i32 %op17)
%op19 = load i32, i32* %op1
%op20 = sub i32 %op19, 2
%op21 = call i32 @fibonacci(i32 %op20)
%op22 = add i32 %op18, %op21
ret i32 %op22
}
define i32 @main() {
label_entry:
%op0 = alloca i32
%op1 = alloca i32
store i32 10, i32* %op0
store i32 0, i32* %op1
br label %label2
label2: ; preds = %label_entry, %label8
%op3 = load i32, i32* %op1
%op4 = load i32, i32* %op0
%op5 = icmp slt i32 %op3, %op4
%op6 = zext i1 %op5 to i32
%op7 = icmp ne i32 %op6, 0
br i1 %op7, label %label8, label %label13
label8: ; preds = %label2
%op9 = load i32, i32* %op1
%op10 = call i32 @fibonacci(i32 %op9)
call void @output(i32 %op10)
%op11 = load i32, i32* %op1
%op12 = add i32 %op11, 1
store i32 %op12, i32* %op1
br label %label2
label13: ; preds = %label2
ret i32 0
}
.text
.globl fibonacci
.type fibonacci, @function
fibonacci:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -80
st.w $a0, $fp, -20
.fibonacci_label_entry:
# %op1 = alloca i32
addi.d $t0, $fp, -32
st.d $t0, $fp, -28
# store i32 %arg0, i32* %op1
ld.d $t0, $fp, -28
ld.w $t1, $fp, -20
st.w $t1, $t0, 0
# %op2 = load i32, i32* %op1
ld.d $t0, $fp, -28
ld.w $t0, $t0, 0
st.w $t0, $fp, -36
# %op3 = icmp eq i32 %op2, 0
ld.w $t0, $fp, -36
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltui $t2, $t2, 1
st.b $t2, $fp, -37
# %op4 = zext i1 %op3 to i32
ld.b $t0, $fp, -37
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -41
# %op5 = icmp ne i32 %op4, 0
ld.w $t0, $fp, -41
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -42
# br i1 %op5, label %label6, label %label8
ld.b $t0, $fp, -42
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .fibonacci_label6
b .fibonacci_label8
.fibonacci_label6:
# ret i32 0
addi.w $a0, $zero, 0
b fibonacci_exit
.fibonacci_label7:
# ret i32 0
addi.w $a0, $zero, 0
b fibonacci_exit
.fibonacci_label8:
# %op9 = load i32, i32* %op1
ld.d $t0, $fp, -28
ld.w $t0, $t0, 0
st.w $t0, $fp, -46
# %op10 = icmp eq i32 %op9, 1
ld.w $t0, $fp, -46
addi.w $t1, $zero, 1
xor $t2, $t0, $t1
sltui $t2, $t2, 1
st.b $t2, $fp, -47
# %op11 = zext i1 %op10 to i32
ld.b $t0, $fp, -47
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -51
# %op12 = icmp ne i32 %op11, 0
ld.w $t0, $fp, -51
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -52
# br i1 %op12, label %label13, label %label15
ld.b $t0, $fp, -52
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .fibonacci_label13
b .fibonacci_label15
.fibonacci_label13:
# ret i32 1
addi.w $a0, $zero, 1
b fibonacci_exit
.fibonacci_label14:
# br label %label7
b .fibonacci_label7
.fibonacci_label15:
# %op16 = load i32, i32* %op1
ld.d $t0, $fp, -28
ld.w $t0, $t0, 0
st.w $t0, $fp, -56
# %op17 = sub i32 %op16, 1
ld.w $t0, $fp, -56
addi.w $t1, $zero, 1
sub.w $t2, $t0, $t1
st.w $t2, $fp, -60
# %op18 = call i32 @fibonacci(i32 %op17)
ld.w $a0, $fp, -60
bl fibonacci
st.w $a0, $fp, -64
# %op19 = load i32, i32* %op1
ld.d $t0, $fp, -28
ld.w $t0, $t0, 0
st.w $t0, $fp, -68
# %op20 = sub i32 %op19, 2
ld.w $t0, $fp, -68
addi.w $t1, $zero, 2
sub.w $t2, $t0, $t1
st.w $t2, $fp, -72
# %op21 = call i32 @fibonacci(i32 %op20)
ld.w $a0, $fp, -72
bl fibonacci
st.w $a0, $fp, -76
# %op22 = add i32 %op18, %op21
ld.w $t0, $fp, -64
ld.w $t1, $fp, -76
add.w $t2, $t0, $t1
st.w $t2, $fp, -80
# ret i32 %op22
ld.w $a0, $fp, -80
b fibonacci_exit
fibonacci_exit:
addi.d $sp, $sp, 80
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
.globl main
.type main, @function
main:
st.d $ra, $sp, -8
st.d $fp, $sp, -16
addi.d $fp, $sp, 0
addi.d $sp, $sp, -80
.main_label_entry:
# %op0 = alloca i32
addi.d $t0, $fp, -28
st.d $t0, $fp, -24
# %op1 = alloca i32
addi.d $t0, $fp, -40
st.d $t0, $fp, -36
# store i32 10, i32* %op0
ld.d $t0, $fp, -24
addi.w $t1, $zero, 10
st.w $t1, $t0, 0
# store i32 0, i32* %op1
ld.d $t0, $fp, -36
addi.w $t1, $zero, 0
st.w $t1, $t0, 0
# br label %label2
b .main_label2
.main_label2:
# %op3 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -44
# %op4 = load i32, i32* %op0
ld.d $t0, $fp, -24
ld.w $t0, $t0, 0
st.w $t0, $fp, -48
# %op5 = icmp slt i32 %op3, %op4
ld.w $t0, $fp, -44
ld.w $t1, $fp, -48
slt $t2, $t0, $t1
st.b $t2, $fp, -49
# %op6 = zext i1 %op5 to i32
ld.b $t0, $fp, -49
bstrpick.w $t0, $t0, 0, 0
st.w $t0, $fp, -53
# %op7 = icmp ne i32 %op6, 0
ld.w $t0, $fp, -53
addi.w $t1, $zero, 0
xor $t2, $t0, $t1
sltu $t2, $zero, $t2
st.b $t2, $fp, -54
# br i1 %op7, label %label8, label %label13
ld.b $t0, $fp, -54
bstrpick.d $t0, $t0, 0, 0
bne $t0, $zero, .main_label8
b .main_label13
.main_label8:
# %op9 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -58
# %op10 = call i32 @fibonacci(i32 %op9)
ld.w $a0, $fp, -58
bl fibonacci
st.w $a0, $fp, -62
# call void @output(i32 %op10)
ld.w $a0, $fp, -62
bl output
# %op11 = load i32, i32* %op1
ld.d $t0, $fp, -36
ld.w $t0, $t0, 0
st.w $t0, $fp, -66
# %op12 = add i32 %op11, 1
ld.w $t0, $fp, -66
addi.w $t1, $zero, 1
add.w $t2, $t0, $t1
st.w $t2, $fp, -70
# store i32 %op12, i32* %op1
ld.d $t0, $fp, -36
ld.w $t1, $fp, -70
st.w $t1, $t0, 0
# br label %label2
b .main_label2
.main_label13:
# ret i32 0
addi.w $a0, $zero, 0
b main_exit
main_exit:
addi.d $sp, $sp, 80
ld.d $ra, $sp, -8
ld.d $fp, $sp, -16
jr $ra
int main(void) {
output(input());
return 0;
}
int main(void) {
output(111);
return 111;
}
program
--fun-declaration: main
----compound-stmt
------expression-stmt
--------simple-expression
----------additive-expression
------------term
--------------call: output()
----------------simple-expression
------------------additive-expression
--------------------term
----------------------num (int): 111
------return-stmt
--------simple-expression
----------additive-expression
------------term
--------------num (int): 111
int main(void) {
float a;
float b;
float c;
a = 1.1;
b = 1.5;
c = 1.2;
outputFloat(a * b + c);
return 0;
}
/*
用 gcc 编译此文件生成汇编代码时,命令为 gcc -include io.h -S 10-float.c
其中 io.h 位于 src/io/io.h,
也可以在本文件开头加上 void outputFloat(float x);
*/
/* float function call */
float mod(float x, float y) {
int div;
div = x / y;
return x - div * y;
}
int main(void) {
float a;
float b;
a = 11.2;
b = 2.2;
outputFloat(mod(a, b));
return 0;
}
int seed;
int randomLCG(void) {
seed = seed * 1103515245 + 12345;
return seed;
}
int randBin(void) {
if (randomLCG() > 0)
return 1;
else
return 0;
}
/* random walk */
int returnToZeroSteps(void) {
int x;
int steps;
x = 0;
steps = 0;
while (steps < 20) {
if (randBin())
x = x + 1;
else
x = x - 1;
steps = steps + 1;
if (x == 0)
return steps;
}
return 20;
}
int main(void) {
int i;
i = 0;
seed = 3407;
while (i < 20) {
output(returnToZeroSteps());
i = i + 1;
}
return 0;
}
4
2
2
4
8
2
2
2
2
2
6
2
10
8
4
2
20
2
2
8
0
/* 01 背包问题 */
int n;
int m;
int w[5];
int v[5];
int dp[66]; /* dp[n * 11 + size] 表示前 n 个物品放入容量为 size 的背包中的最大价值,初始化为 -1 */
int max(int a, int b) {
if (a > b)
return a;
else
return b;
}
/* 状态转移方程:
dp[n][size] = max(dp[n - 1][size], dp[n - 1][size - w[n]] + v[n])
边界条件:
dp[n][size <= 0] = 0
dp[0][size] = 0 */
int knapsack(int n, int size) {
int result;
if (size <= 0)
return 0;
if (n == 0)
return 0;
if (dp[n * 11 + size] >= 0)
return dp[n * 11 + size];
if (size < w[n - 1])
result = knapsack(n - 1, size);
else
result = max(knapsack(n - 1, size), knapsack(n - 1, size - w[n - 1]) + v[n - 1]);
dp[n * 11 + size] = result;
return result;
}
int main(void) {
int i;
i = 0;
n = 5;
m = 10;
w[0] = 2;
w[1] = 2;
w[2] = 6;
w[3] = 5;
w[4] = 4;
v[0] = 6;
v[1] = 3;
v[2] = 5;
v[3] = 4;
v[4] = 6;
while (i < 66) {
dp[i] = 0 - 1;
i = i + 1;
}
output(knapsack(n, m));
return 0;
}
int main(void) {
int a;
int b;
int c;
a = 23;
b = 25;
c = 4;
return a + b * c;
}
int main(void) {
output(11);
output(22222);
return 0;
}
int main(void) {
int a;
int b;
int c;
a = 11;
b = 22;
c = 33;
/* max value */
if (a > b) {
if (a > c)
output(a);
else
output(c);
} else {
if (c < b)
output(b);
else
output(c);
}
return 0;
}
int main(void) {
int n;
int i;
n = 10;
i = 0;
while (i < n) {
output(i);
i = i + 1;
}
return 0;
}
int main(void) {
int a[10];
int i;
i = 0;
a[0] = 11;
a[4] = 22;
a[9] = 33;
output(a[0]);
output(a[4]);
output(a[9]);
return 0;
}
int min(int a, int b) {
if (a <= b)
return a;
else
return b;
}
int main(void) {
int a;
int b;
int c;
a = 11;
b = 22;
c = 33;
output(min(a, b));
output(min(b, c));
output(min(c, a));
return 0;
}
int store(int arr[], int index, int value) {
arr[index] = value;
return value;
}
int main(void) {
int a[10];
int i;
int sum;
i = 0;
while (i < 10) {
store(a, i, i * 2);
i = i + 1;
}
sum = 0;
i = 0;
while (i < 10) {
sum = sum + a[i];
i = i + 1;
}
output(sum);
return 0;
}
int fibonacci(int n) {
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
int main(void) {
int n;
int i;
n = 10;
i = 0;
while (i < n) {
output(fibonacci(i));
i = i + 1;
}
return 0;
}
add_executable(
stu_assign_codegen
stu_cpp/assign_codegen.cpp
)
target_link_libraries(
stu_assign_codegen
IR_lib
codegen
)
add_executable(
stu_function_codegen
stu_cpp/function_codegen.cpp
)
target_link_libraries(
stu_function_codegen
IR_lib
codegen
)
add_executable(
stu_icmp_codegen
stu_cpp/icmp_codegen.cpp
)
target_link_libraries(
stu_icmp_codegen
IR_lib
codegen
)
add_executable(
stu_fcmp_codegen
stu_cpp/fcmp_codegen.cpp
)
target_link_libraries(
stu_fcmp_codegen
IR_lib
codegen
)
add_executable(
stu_float_codegen
stu_cpp/float_codegen.cpp
)
target_link_libraries(
stu_float_codegen
IR_lib
codegen
)
add_executable(
stu_global_codegen
stu_cpp/global_codegen.cpp
)
target_link_libraries(
stu_global_codegen
IR_lib
codegen
)
define i32 @main() {
label_entry:
%op0 = alloca [10 x i32]
%op1 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 0
store i32 10, i32* %op1
%op2 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 1
%op3 = load i32, i32* %op1
%op4 = mul i32 %op3, 3
store i32 %op4, i32* %op2
%op5 = load i32, i32* %op2
ret i32 %op5
}
define i32 @main() {
label_entry:
; 5.5 (0x40b00000) > 1.0 (0x3f800000)
%op0 = fcmp ugt float 0x4016000000000000, 0x3ff0000000000000
%op1 = zext i1 %op0 to i32
%op2 = icmp ne i32 %op1, 0
br i1 %op2, label %label3, label %label4
label3: ; preds = %label_entry
ret i32 233
label4: ; preds = %label_entry
ret i32 0
}
define i32 @main() {
label_entry:
%op0 = alloca float
store float 0x40091eb860000000, float* %op0 ; 3.14, FP32 0x4048f5c3
%op1 = load float, float* %op0
%op2 = fptosi float %op1 to i32
ret i32 %op2
}
define i32 @callee(i32 %arg0) {
label_entry:
%op1 = alloca i32
store i32 %arg0, i32* %op1
%op2 = load i32, i32* %op1
%op3 = mul i32 3, %op2
ret i32 %op3
}
define i32 @main() {
label_entry:
%op0 = call i32 @callee(i32 110)
ret i32 %op0
}
@a = global i32 zeroinitializer
define i32 @main() {
label_entry:
store i32 10, i32* @a
%op0 = load i32, i32* @a
ret i32 %op0
}
define i32 @main() {
label_entry:
%op0 = icmp sgt i32 5, 1
%op1 = zext i1 %op0 to i32
%op2 = icmp ne i32 %op1, 0
br i1 %op2, label %label3, label %label4
label3: ; preds = %label_entry
ret i32 233
label4: ; preds = %label_entry
ret i32 0
}
#include "ASMInstruction.hpp"
#include "CodeGen.hpp"
#include "Module.hpp"
#include <iostream>
#include <memory>
#include <unordered_map>
void translate_main(CodeGen *codegen); // 将 main 函数翻译为汇编代码
int main() {
auto *module = new Module();
auto *codegen = new CodeGen(module);
// 告诉汇编器将汇编放到代码段
codegen->append_inst(".text", ASMInstruction::Atrribute);
translate_main(codegen);
std::cout << codegen->print();
delete codegen;
delete module;
return 0;
}
// TODO: 按照提示补全
void translate_main(CodeGen *codegen) {
std::unordered_map<std::string, int> offset_map;
/* 声明 main 函数 */
codegen->append_inst(".globl main", ASMInstruction::Atrribute);
codegen->append_inst(".type main, @function", ASMInstruction::Atrribute);
/* main 函数开始 */
codegen->append_inst("main", ASMInstruction::Label); // main 函数标签
/* main 函数的 Prologue (序言) */
// 保存返回地址
codegen->append_inst("st.d $ra, $sp, -8");
// 保存老的 fp
codegen->append_inst("st.d $fp, $sp, -16");
// 设置新的 fp
codegen->append_inst("addi.d $fp, $sp, 0");
// 为栈帧分配空间. 思考: 为什么是 96 字节?
codegen->append_inst("addi.d $sp, $sp, -96");
/* main 函数的 label_entry */
codegen->append_inst(".main_label_entry", ASMInstruction::Label);
/* %op0 = alloca [10 x i32] */
// 在汇编中写入注释, 方便 debug
codegen->append_inst("%op0 = alloca [10 x i32]", ASMInstruction::Comment);
// 将数组的地址写入 %op0 对应的内存空间中
// 首先计算数组的地址对应的偏移量, 按照我们在栈式分配中介绍的规则, 数组的空
// 间紧挨着 %op0 的空间, 数组的地址为这段空间的最小值.
// 然后将数组的地址写入 %op0 对应的内存空间中.
// 你需要思考:
// - %op0 的大小是多少字节?
// - %op0 的偏移量是多少字节?
// - 数组的大小是多少字节?
// - 数组的偏移量是多少字节?
offset_map["%op0"] = ; // TODO: 请填空
offset_map["array"] = ; // TODO: 请填空
codegen->append_inst("addi.d",
{"$t0", "$fp", std::to_string(offset_map["array"])});
codegen->append_inst("st.d",
{"$t0", "$fp", std::to_string(offset_map["%op0"])});
/* %op1 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 0 */
codegen->append_inst(
"%op1 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 0",
ASMInstruction::Comment);
// 将 gep 的值写入 %op1 对应的内存空间中
// 你可以手动计算 gep 的值, 或者使用指令计算 gep 的值
// 你需要思考 %op1 的偏移量是多少字节
offset_map["%op1"] = ; // TODO: 请填空
// 获得数组的地址, 将其写入 $t0 中
codegen->append_inst("ld.d",
{"$t0", "$fp", std::to_string(offset_map["%op0"])});
// TODO: 计算 %op1 的值, 并将其写入 %op1 对应的内存空间中
codegen->append_inst("");
/* store i32 10, i32* %op1 */
codegen->append_inst("store i32 10, i32* %op1", ASMInstruction::Comment);
// 将 10 写入数组 (%op1 指向的空间) 中, 需要先获得 %op1 的值
codegen->append_inst("ld.d",
{"$t0", "$fp", std::to_string(offset_map["%op1"])});
codegen->append_inst("addi.w $t1, $zero, 10");
codegen->append_inst("st.w $t1, $t0, 0");
/* %op2 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 1 */
codegen->append_inst(
"%op2 = getelementptr [10 x i32], [10 x i32]* %op0, i32 0, i32 1",
ASMInstruction::Comment);
// 将 gep 的值写入 %op2 对应的内存空间中
// 你可以手动计算 gep 的值, 或者使用指令计算 gep 的值
// 你需要思考 %op2 的偏移量是多少字节
offset_map["%op2"] = ; // TODO: 请填空
// 获得数组的地址, 将其写入 $t0 中
codegen->append_inst("ld.d",
{"$t0", "$fp", std::to_string(offset_map["%op0"])});
// TODO: 计算 gep 的值, 并将其写入 %op2 对应的内存空间中
codegen->append_inst("");
/* %op3 = load i32, i32* %op1 */
codegen->append_inst("%op3 = load i32, i32* %op1", ASMInstruction::Comment);
// 将 %op1 指向的空间中存储的值写入 %op3 对应的内存空间中
offset_map["%op3"] = ; // TODO: 请填空
// TODO: 先获得 %op1 的值, 然后获得 %op1 指向的空间的值, 最后将这个值写入
// %op3 对应的内存空间中
codegen->append_inst("");
/* %op4 = mul i32 %op3, 3 */
codegen->append_inst("%op4 = mul i32 %op3, 3", ASMInstruction::Comment);
offset_map["%op4"] = ; // TODO: 请填空
// TODO: 先获得 %op3 的值, 然后将其乘以 3, 最后将结果写入 %op4 对应的内存空
// 间中
codegen->append_inst("");
/* store i32 %op4, i32* %op2 */
codegen->append_inst("store i32 %op4, i32* %op2", ASMInstruction::Comment);
// 将 %op4 的值写入 %op2 指向的空间中
// TODO: 先获得 %op4 的值, 然后将其写入 %op2 指向的空间中
codegen->append_inst("");
/* %op5 = load i32, i32* %op2 */
// 将 %op2 指向的空间中存储的值写入 %op5 对应的内存空间中
offset_map["%op5"] = ; // TODO: 请填空
// TODO: 先获得 %op2 的值, 然后获得 %op2 指向的空间的值, 最后将这个值写入
// %op5 对应的内存空间中
codegen->append_inst("");
/* ret i32 %op5 */
codegen->append_inst("ret i32 %op5", ASMInstruction::Comment);
// TODO: 将 %op5 的值写入 $a0 中
codegen->append_inst("");
// 思考: 为什么不在这里 jr $ra, 而是跳转到 main_exit?
codegen->append_inst("b main_exit");
/* main 函数的 Epilogue (收尾) */
codegen->append_inst("main_exit", ASMInstruction::Label);
// 释放栈帧空间
codegen->append_inst("addi.d $sp, $sp, 96");
// 恢复 ra
codegen->append_inst("ld.d $ra, $sp, -8");
// 恢复 fp
codegen->append_inst("ld.d $fp, $sp, -16");
// 返回
codegen->append_inst("jr $ra");
}
#include "ASMInstruction.hpp"
#include "CodeGen.hpp"
#include "Module.hpp"
#include <iostream>
#include <memory>
#include <unordered_map>
void translate_main(CodeGen *codegen); // 将 main 函数翻译为汇编代码
int main() {
auto *module = new Module();
auto *codegen = new CodeGen(module);
// 告诉汇编器将汇编放到代码段
codegen->append_inst(".text", ASMInstruction::Atrribute);
translate_main(codegen);
std::cout << codegen->print();
delete codegen;
delete module;
return 0;
}
// TODO: 按照提示补全
void translate_main(CodeGen *codegen) {
std::unordered_map<std::string, int> offset_map;
/* 声明 main 函数 */
codegen->append_inst(".globl main", ASMInstruction::Atrribute);
codegen->append_inst(".type main, @function", ASMInstruction::Atrribute);
/* main 函数开始 */
codegen->append_inst("main", ASMInstruction::Label); // main 函数标签
/* main 函数的 Prologue (序言) */
// 保存返回地址
codegen->append_inst("st.d $ra, $sp, -8");
// 保存老的 fp
codegen->append_inst("st.d $fp, $sp, -16");
// 设置新的 fp
codegen->append_inst("addi.d $fp, $sp, 0");
// 为栈帧分配空间. 思考: 为什么是 32 字节?
codegen->append_inst("addi.d $sp, $sp, -32");
/* main 函数的 label_entry */
codegen->append_inst(".main_label_entry", ASMInstruction::Label);
/* %op0 = fcmp ugt float 0x4016000000000000, 0x3ff0000000000000 */
// 在汇编中写入注释, 方便 debug
codegen->append_inst(
"%op0 = fcmp ugt float 0x4016000000000000, 0x3ff0000000000000",
ASMInstruction::Comment);
// 将比较结果写入 %op0 对应的内存空间中
offset_map["%op0"] = ; // TODO: 请填空
// TODO: 将 5.5 (0x40b00000) 加载到浮点寄存器中
codegen->append_inst("");
// TODO: 将 1.0 (0x3f800000) 加载到浮点寄存器中
codegen->append_inst("");
// TODO: 使用 fcmp.slt.s 进行比较, 比较结果在浮点标志寄存器中, 你需要思考
// 如何将浮点标志寄存器中的值写入内存. 提示: 尝试使用 bcnez 指令
codegen->append_inst("");
/* %op1 = zext i1 %op0 to i32 */
codegen->append_inst("%op1 = zext i1 %op0 to i32", ASMInstruction::Comment);
// 将 %op0 的值从 i1 类型转换为 i32 类型, 并将结果写入到 %op1 对应的内存空
// 间中
offset_map["%op1"] = ; // TODO: 请填空
// TODO: 获得 %op0 的值, 然后进行转换, 最后将结果写入 %op1
// 思考: 怎么转换? 需不需要显式地使用某些指令转换?
codegen->append_inst("");
/* %op2 = icmp ne i32 %op1, 0 */
codegen->append_inst("%op2 = icmp ne i32 %op1, 0", ASMInstruction::Comment);
// 比较 %op1 和 0, 并将结果写入 %op2 对应的内存空间中
offset_map["%op2"] = ; // TODO: 请填空
// TODO: 获得 %op1 的值, 然后进行比较, 最后将结果写入 %op2
// 思考: 如何比较? 能否不使用跳转指令计算结果?
// 提示: 尝试使用 xor/xori 和 slt/sltu/slti/sltui 计算比较结果
codegen->append_inst("");
/* br i1 %op2, label %label3, label %label4 */
codegen->append_inst("br i1 %op2, label %label3, label %label4",
ASMInstruction::Comment);
// TODO: 获得 %op2 的值, 并根据 %op2 的值跳转到 label3 或者 label4
// 提示: 汇编中对应的标签分别为 .main_label3 和 .main_label4
codegen->append_inst("");
/* label3: */
codegen->append_inst(".main_label3", ASMInstruction::Label);
/* ret i32 233 */
codegen->append_inst("ret i32 233", ASMInstruction::Comment);
// 将 233 写入 $a0 中
codegen->append_inst("addi.w $a0, $zero, 233");
codegen->append_inst("b main_exit");
/* label4: */
codegen->append_inst(".main_label4", ASMInstruction::Label);
/* ret i32 0 */
codegen->append_inst("ret i32 0", ASMInstruction::Comment);
// 将 0 写入 $a0 中
codegen->append_inst("addi.w $a0, $zero, 0");
codegen->append_inst("b main_exit");
/* main 函数的 Epilogue (收尾) */
codegen->append_inst("main_exit", ASMInstruction::Label);
// 释放栈帧空间
codegen->append_inst("addi.d $sp, $sp, 32");
// 恢复 ra
codegen->append_inst("ld.d $ra, $sp, -8");
// 恢复 fp
codegen->append_inst("ld.d $fp, $sp, -16");
// 返回
codegen->append_inst("jr $ra");
}
#include "ASMInstruction.hpp"
#include "CodeGen.hpp"
#include "Module.hpp"
#include <iostream>
#include <memory>
#include <unordered_map>
void translate_main(CodeGen *codegen); // 将 main 函数翻译为汇编代码
int main() {
auto *module = new Module();
auto *codegen = new CodeGen(module);
// 告诉汇编器将汇编放到代码段
codegen->append_inst(".text", ASMInstruction::Atrribute);
translate_main(codegen);
std::cout << codegen->print();
delete codegen;
delete module;
return 0;
}
// TODO: 按照提示补全
void translate_main(CodeGen *codegen) {
std::unordered_map<std::string, int> offset_map;
/* 声明 main 函数 */
codegen->append_inst(".globl main", ASMInstruction::Atrribute);
codegen->append_inst(".type main, @function", ASMInstruction::Atrribute);
/* main 函数开始 */
codegen->append_inst("main", ASMInstruction::Label); // main 函数标签
/* main 函数的 Prologue (序言) */
// 保存返回地址
codegen->append_inst("st.d $ra, $sp, -8");
// 保存老的 fp
codegen->append_inst("st.d $fp, $sp, -16");
// 设置新的 fp
codegen->append_inst("addi.d $fp, $sp, 0");
// 为栈帧分配空间. 思考: 为什么是 48 字节?
codegen->append_inst("addi.d $sp, $sp, -48");
/* main 函数的 label_entry */
codegen->append_inst(".main_label_entry", ASMInstruction::Label);
/* %op0 = alloca float */
// 在汇编中写入注释, 方便 debug
codegen->append_inst("%op0 = alloca float", ASMInstruction::Comment);
// 将浮点数的地址写入 %op0 对应的内存空间中
offset_map["%op0"] = ; // TODO: 请填空
offset_map["*%op0"] = ; // TODO: 请填空
codegen->append_inst("addi.d",
{"$t0", "$fp", std::to_string(offset_map["*%op0"])});
codegen->append_inst("st.d",
{"$t0", "$fp", std::to_string(offset_map["%op0"])});
/* store float 0x40091eb860000000, float* %op0 */
codegen->append_inst("store float 0x40091eb860000000, float* %op0",
ASMInstruction::Comment);
// 将 3.14 (0x4048f5c3) 写入 %op0 指向的内存空间中
// 获得 %op0 的值
codegen->append_inst("ld.d",
{"$t0", "$fp", std::to_string(offset_map["%op0"])});
// TODO: 将 0x4048f5c3 加载到通用寄存器或者浮点寄存器中
codegen->append_inst("");
// TODO: 将通用寄存器或者浮点寄存器中的值写入 %op0 对应的内存空间中
codegen->append_inst("");
/* %op1 = load float, float* %op0 */
codegen->append_inst("%op1 = load float, float* %op0",
ASMInstruction::Comment);
// TODO: 先获得 %op0 的值, 然后获得 %op0 指向的空间的值, 最后将这个值写入
// %op1 对应的内存空间中
offset_map["%op1"] = ; // TODO: 请填空
codegen->append_inst("");
/* %op2 = fptosi float %op1 to i32 */
codegen->append_inst("%op2 = fptosi float %op1 to i32",
ASMInstruction::Comment);
// TODO: 使用 ftintrz.w.s 指令进行转换, 并将结果写入 %op2 对应的内存空间中
offset_map["%op2"] = ; // TODO: 请填空
codegen->append_inst("");
/* ret i32 %op2 */
codegen->append_inst("ret i32 %op2", ASMInstruction::Comment);
// TODO: 将 %op2 的值写入 $a0 中
codegen->append_inst("");
codegen->append_inst("b main_exit");
/* main 函数的 Epilogue (收尾) */
codegen->append_inst("main_exit", ASMInstruction::Label);
// 释放栈帧空间
codegen->append_inst("addi.d $sp, $sp, 48");
// 恢复 ra
codegen->append_inst("ld.d $ra, $sp, -8");
// 恢复 fp
codegen->append_inst("ld.d $fp, $sp, -16");
// 返回
codegen->append_inst("jr $ra");
}
#include "ASMInstruction.hpp"
#include "CodeGen.hpp"
#include "Module.hpp"
#include <iostream>
#include <memory>
#include <unordered_map>
void translate_main(CodeGen *codegen); // 将 main 函数翻译为汇编代码
void translate_callee(CodeGen *codegen); // 将 callee 函数翻译为汇编代码
int main() {
auto *module = new Module();
auto *codegen = new CodeGen(module);
// 告诉汇编器将汇编放到代码段
codegen->append_inst(".text", ASMInstruction::Atrribute);
translate_callee(codegen);
translate_main(codegen);
std::cout << codegen->print();
delete codegen;
delete module;
return 0;
}
// TODO: 按照提示补全
void translate_callee(CodeGen *codegen) {
std::unordered_map<std::string, int> offset_map;
/* 声明 callee 函数 */
codegen->append_inst(".globl callee", ASMInstruction::Atrribute);
codegen->append_inst(".type callee, @function", ASMInstruction::Atrribute);
/* callee 函数开始 */
codegen->append_inst("callee", ASMInstruction::Label); // main 函数标签
/* callee 函数的 Prologue (序言) */
// 保存返回地址
codegen->append_inst("st.d $ra, $sp, -8");
// 保存老的 fp
codegen->append_inst("st.d $fp, $sp, -16");
// 设置新的 fp
codegen->append_inst("addi.d $fp, $sp, 0");
// 为栈帧分配空间. 思考: 为什么是 48 字节?
codegen->append_inst("addi.d $sp, $sp, -48");
// 为参数分配空间
offset_map["%arg0"] = ; // TODO: 请填空
codegen->append_inst("st.w",
{"$a0", "$fp", std::to_string(offset_map["%arg0"])});
/* callee 函数的 label_entry */
codegen->append_inst(".callee_label_entry", ASMInstruction::Label);
/* %op1 = alloca i32 */
// 在汇编中写入注释, 方便 debug
codegen->append_inst("%op1 = alloca i32", ASMInstruction::Comment);
// 将 alloca 的地址写入 %op1 对应的内存空间中
offset_map["%op1"] = ; // TODO: 请填空
offset_map["*%op1"] = ; // TODO: 请填空
codegen->append_inst("addi.d",
{"$t0", "$fp", std::to_string(offset_map["*%op1"])});
codegen->append_inst("st.d",
{"$t0", "$fp", std::to_string(offset_map["%op1"])});
/* store i32 %arg0, i32* %op1 */
codegen->append_inst("store i32 %arg0, i32* %op1", ASMInstruction::Comment);
// 将 %arg0 的值写入 %op1 对应的内存空间中
codegen->append_inst("ld.d",
{"$t0", "$fp", std::to_string(offset_map["%op1"])});
codegen->append_inst("ld.w",
{"$t1", "$fp", std::to_string(offset_map["%arg0"])});
codegen->append_inst("st.w $t1, $t0, 0");
/* %op2 = load i32, i32* %op1 */
codegen->append_inst("%op2 = load i32, i32* %op1", ASMInstruction::Comment);
// 将 %op1 对应的内存空间的值写入 %op2 对应的内存空间中
offset_map["%op2"] = ; // TODO: 请填空
codegen->append_inst("ld.d",
{"$t0", "$fp", std::to_string(offset_map["%op1"])});
codegen->append_inst("ld.w $t1, $t0, 0");
codegen->append_inst("st.w",
{"$t1", "$fp", std::to_string(offset_map["%op2"])});
/* %op3 = mul i32 3, %op2 */
codegen->append_inst("%op3 = mul i32 3, %op2", ASMInstruction::Comment);
// 将 %op2 的值乘以 3, 并将结果写入 %op3 对应的内存空间中
offset_map["%op3"] = ; // TODO: 请填空
codegen->append_inst("ld.w",
{"$t0", "$fp", std::to_string(offset_map["%op2"])});
codegen->append_inst("addi.w $t1, $zero, 3");
codegen->append_inst("mul.w $t0, $t0, $t1");
codegen->append_inst("st.w",
{"$t0", "$fp", std::to_string(offset_map["%op3"])});
/* ret i32 %op3 */
codegen->append_inst("ret i32 %op3", ASMInstruction::Comment);
// 将 %op3 的值写入 $a0 中
codegen->append_inst("ld.w",
{"$a0", "$fp", std::to_string(offset_map["%op3"])});
codegen->append_inst("b callee_exit");
/* callee 函数的 Epilogue (收尾) */
codegen->append_inst("callee_exit", ASMInstruction::Label);
// 释放栈帧空间
codegen->append_inst("addi.d $sp, $sp, 48");
// 恢复 ra
codegen->append_inst("ld.d $ra, $sp, -8");
// 恢复 fp
codegen->append_inst("ld.d $fp, $sp, -16");
// 返回
codegen->append_inst("jr $ra");
}
// TODO: 按照提示补全
void translate_main(CodeGen *codegen) {
std::unordered_map<std::string, int> offset_map;
/* 声明 main 函数 */
codegen->append_inst(".globl main", ASMInstruction::Atrribute);
codegen->append_inst(".type main, @function", ASMInstruction::Atrribute);
/* main 函数开始 */
codegen->append_inst("main", ASMInstruction::Label); // main 函数标签
/* main 函数的 Prologue (序言) */
// 保存返回地址
codegen->append_inst("st.d $ra, $sp, -8");
// 保存老的 fp
codegen->append_inst("st.d $fp, $sp, -16");
// 设置新的 fp
codegen->append_inst("addi.d $fp, $sp, 0");
// 为栈帧分配空间. 思考: 为什么是 32 字节?
codegen->append_inst("addi.d $sp, $sp, -32");
/* main 函数的 label_entry */
codegen->append_inst(".main_label_entry", ASMInstruction::Label);
/* %op0 = call i32 @callee(i32 110) */
// 在汇编中写入注释, 方便 debug
codegen->append_inst("%op0 = call i32 @callee(i32 110)",
ASMInstruction::Comment);
offset_map["%op0"] = ; // TODO: 请填空
// TODO: 将参数写入参数寄存器
codegen->append_inst("");
// TODO: 调用 callee 函数
codegen->append_inst("");
// 将返回值写入 %op0 对应的内存空间中
codegen->append_inst("st.w",
{"$a0", "$fp", std::to_string(offset_map["%op0"])});
/* ret i32 %op0 */
codegen->append_inst("ret i32 %op0", ASMInstruction::Comment);
codegen->append_inst("ld.w",
{"$a0", "$fp", std::to_string(offset_map["%op0"])});
codegen->append_inst("b main_exit");
/* main 函数的 Epilogue (收尾) */
codegen->append_inst("main_exit", ASMInstruction::Label);
// 释放栈帧空间
codegen->append_inst("addi.d $sp, $sp, 32");
// 恢复 ra
codegen->append_inst("ld.d $ra, $sp, -8");
// 恢复 fp
codegen->append_inst("ld.d $fp, $sp, -16");
// 返回
codegen->append_inst("jr $ra");
}
#include "ASMInstruction.hpp"
#include "CodeGen.hpp"
#include "Module.hpp"
#include <iostream>
#include <memory>
#include <unordered_map>
void declare_global(CodeGen *codegen); // 声明全局变量 a
void translate_main(CodeGen *codegen); // 将 main 函数翻译为汇编代码
int main() {
auto *module = new Module();
auto *codegen = new CodeGen(module);
// 告诉汇编器将汇编放到代码段
codegen->append_inst(".text", ASMInstruction::Atrribute);
declare_global(codegen);
codegen->append_inst(".text", ASMInstruction::Atrribute);
translate_main(codegen);
std::cout << codegen->print();
delete codegen;
delete module;
return 0;
}
void declare_global(CodeGen *codegen) {
// 声明全局变量 a
// 将 a 放到 .bss 段中
codegen->append_inst(".section .bss, \"aw\", @nobits",
ASMInstruction::Atrribute);
// 标记 a 为全局变量
codegen->append_inst(".globl a", ASMInstruction::Atrribute);
// 标记 a 为数据对象 (变量)
codegen->append_inst(".type a, @object", ASMInstruction::Atrribute);
// 标记 a 的大小为 4 字节
codegen->append_inst(".size a, 4", ASMInstruction::Atrribute);
// a 的标签
codegen->append_inst("a", ASMInstruction::Label);
// 为 a 分配空间
codegen->append_inst(".space 4");
}
// TODO: 按照提示补全
void translate_main(CodeGen *codegen) {
std::unordered_map<std::string, int> offset_map;
/* 声明 main 函数 */
codegen->append_inst(".globl main", ASMInstruction::Atrribute);
codegen->append_inst(".type main, @function", ASMInstruction::Atrribute);
/* main 函数开始 */
codegen->append_inst("main", ASMInstruction::Label); // main 函数标签
/* main 函数的 Prologue (序言) */
// 保存返回地址
codegen->append_inst("st.d $ra, $sp, -8");
// 保存老的 fp
codegen->append_inst("st.d $fp, $sp, -16");
// 设置新的 fp
codegen->append_inst("addi.d $fp, $sp, 0");
// 为栈帧分配空间. 思考: 为什么是 32 字节?
codegen->append_inst("addi.d $sp, $sp, -32");
/* main 函数的 label_entry */
codegen->append_inst(".main_label_entry", ASMInstruction::Label);
/* store i32 10, i32* @a */
// 在汇编中写入注释, 方便 debug
codegen->append_inst("store i32 10, i32* @a", ASMInstruction::Comment);
// 将 10 写入 a 对应的内存空间中
// TODO: 获得 a 的地址
codegen->append_inst("");
// TODO: 将 10 写入 a 对应的内存空间中
codegen->append_inst("");
/* %op0 = load i32, i32* @a */
codegen->append_inst("%op0 = load i32, i32* @a", ASMInstruction::Comment);
// 将 a 的值写入 %op0 对应的内存空间中
offset_map["%op0"] = ; // TODO: 请填空
// TODO: 获得 a 的地址, 并存储在 $t0 中
codegen->append_inst("");
// 将 a 的值写入 %op0 对应的内存空间中
codegen->append_inst("ld.w $t1, $t0, 0");
codegen->append_inst("st.w",
{"$t1", "$fp", std::to_string(offset_map["%op0"])});
/* ret i32 %op0 */
codegen->append_inst("ret i32 %op0", ASMInstruction::Comment);
// 将 %op0 的值写入 $a0
codegen->append_inst("ld.w",
{"$a0", "$fp", std::to_string(offset_map["%op0"])});
codegen->append_inst("b main_exit");
/* main 函数的 Epilogue (收尾) */
codegen->append_inst("main_exit", ASMInstruction::Label);
// 释放栈帧空间
codegen->append_inst("addi.d $sp, $sp, 32");
// 恢复 ra
codegen->append_inst("ld.d $ra, $sp, -8");
// 恢复 fp
codegen->append_inst("ld.d $fp, $sp, -16");
// 返回
codegen->append_inst("jr $ra");
}
#include "ASMInstruction.hpp"
#include "CodeGen.hpp"
#include "Module.hpp"
#include <iostream>
#include <memory>
#include <unordered_map>
void translate_main(CodeGen *codegen); // 将 main 函数翻译为汇编代码
int main() {
auto *module = new Module();
auto *codegen = new CodeGen(module);
// 告诉汇编器将汇编放到代码段
codegen->append_inst(".text", ASMInstruction::Atrribute);
translate_main(codegen);
std::cout << codegen->print();
delete codegen;
delete module;
return 0;
}
// TODO: 按照提示补全
void translate_main(CodeGen *codegen) {
std::unordered_map<std::string, int> offset_map;
/* 声明 main 函数 */
codegen->append_inst(".globl main", ASMInstruction::Atrribute);
codegen->append_inst(".type main, @function", ASMInstruction::Atrribute);
/* main 函数开始 */
codegen->append_inst("main", ASMInstruction::Label); // main 函数标签
/* main 函数的 Prologue (序言) */
// 保存返回地址
codegen->append_inst("st.d $ra, $sp, -8");
// 保存老的 fp
codegen->append_inst("st.d $fp, $sp, -16");
// 设置新的 fp
codegen->append_inst("addi.d $fp, $sp, 0");
// 为栈帧分配空间. 思考: 为什么是 32 字节?
codegen->append_inst("addi.d $sp, $sp, -32");
/* main 函数的 label_entry */
codegen->append_inst(".main_label_entry", ASMInstruction::Label);
/* %op0 = icmp sgt i32 5, 1 */
// 在汇编中写入注释, 方便 debug
codegen->append_inst("%op0 = icmp sgt i32 5, 1", ASMInstruction::Comment);
// 将比较结果写入 %op0 对应的内存空间中
offset_map["%op0"] = ; // TODO: 请填空
codegen->append_inst("addi.w $t0, $zero, 5");
codegen->append_inst("addi.w $t1, $zero, 1");
// TODO: 使用 slt 指令比较, 并将结果写入 %op0 对应的内存空间中
codegen->append_inst("");
codegen->append_inst("");
/* %op1 = zext i1 %op0 to i32 */
codegen->append_inst("%op1 = zext i1 %op0 to i32", ASMInstruction::Comment);
// 将 %op0 的值从 i1 类型转换为 i32 类型, 并将结果写入到 %op1 对应的内存空
// 间中
offset_map["%op1"] = ; // TODO: 请填空
// TODO: 获得 %op0 的值, 然后进行转换, 最后将结果写入 %op1
// 思考: 怎么转换? 需不需要显式地使用某些指令转换?
codegen->append_inst("");
/* %op2 = icmp ne i32 %op1, 0 */
codegen->append_inst("%op2 = icmp ne i32 %op1, 0", ASMInstruction::Comment);
// 比较 %op1 和 0, 并将结果写入 %op2 对应的内存空间中
offset_map["%op2"] = ; // TODO: 请填空
// TODO: 获得 %op1 的值, 然后进行比较, 最后将结果写入 %op2
// 思考: 如何比较? 能否不使用跳转指令计算结果?
// 提示: 尝试使用 xor/xori 和 slt/sltu/slti/sltui 计算比较结果
codegen->append_inst("");
/* br i1 %op2, label %label3, label %label4 */
codegen->append_inst("br i1 %op2, label %label3, label %label4",
ASMInstruction::Comment);
// TODO: 获得 %op2 的值, 并根据 %op2 的值跳转到 label3 或者 label4
// 提示: 汇编中对应的标签分别为 .main_label3 和 .main_label4
codegen->append_inst("");
/* label3: */
codegen->append_inst(".main_label3", ASMInstruction::Label);
/* ret i32 233 */
codegen->append_inst("ret i32 233", ASMInstruction::Comment);
// 将 233 写入 $a0 中
codegen->append_inst("addi.w $a0, $zero, 233");
codegen->append_inst("b main_exit");
/* label4: */
codegen->append_inst(".main_label4", ASMInstruction::Label);
/* ret i32 0 */
codegen->append_inst("ret i32 0", ASMInstruction::Comment);
// 将 0 写入 $a0 中
codegen->append_inst("addi.w $a0, $zero, 0");
codegen->append_inst("b main_exit");
/* main 函数的 Epilogue (收尾) */
codegen->append_inst("main_exit", ASMInstruction::Label);
// 释放栈帧空间
codegen->append_inst("addi.d $sp, $sp, 32");
// 恢复 ra
codegen->append_inst("ld.d $ra, $sp, -8");
// 恢复 fp
codegen->append_inst("ld.d $fp, $sp, -16");
// 返回
codegen->append_inst("jr $ra");
}
add_subdirectory("2-ir-gen/warmup")
\ No newline at end of file
add_subdirectory("2-ir-gen/warmup")
add_subdirectory("3-codegen/warmup")
\ No newline at end of file
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment