Commit f75c9166 authored by jhe's avatar jhe

lab3_impl

parent 1822adc0
......@@ -39,6 +39,7 @@ INCLUDE_DIRECTORIES(
include/cminusfc
include/common
include/lightir
include/codegen
${LLVM_INCLUDE_DIRS}
)
......
#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); }
};
......@@ -4,3 +4,4 @@ add_subdirectory(logging)
add_subdirectory(cminusfc)
add_subdirectory(lightir)
add_subdirectory(io)
add_subdirectory(codegen)
\ No newline at end of file
......@@ -9,6 +9,7 @@ target_link_libraries(
IR_lib
common
syntax
codegen
stdc++fs
)
......
#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 {
......@@ -105,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;
// }
void CodeGen::gen_epilogue() {
append_inst(func_exit_label_name(context.func), ASMInstruction::Label);
if (IS_IMM_12(static_cast<int>(context.frame_size))) {
append_inst("addi.d $sp, $sp, " + std::to_string(context.frame_size));
append_inst("ld.d $ra, $sp, -8");
append_inst("ld.d $fp, $sp, -16");
} else {
load_large_int64(context.frame_size, Reg::t(0));
append_inst("add.d $sp, $sp, $t0");
append_inst("ld.d $ra, $sp, -8");
append_inst("ld.d $fp, $sp, -16");
}
output.emplace_back("jr $ra");
}
void CodeGen::gen_ret() {
if (not context.func->get_return_type()->is_void_type()) {
// 需要把返回值放到 $a0 中
auto *ret_val = context.inst->get_operand(0);
if (ret_val->get_type()->is_float_type()) {
load_to_freg(ret_val, FReg::fa(0));
} else {
load_to_greg(ret_val, Reg::a(0));
}
} else {
append_inst("addi.w $a0, $zero, 0");
}
append_inst("b " + func_exit_label_name(context.func));
}
void CodeGen::gen_br() {
auto *branchInst = static_cast<BranchInst *>(context.inst);
if (branchInst->is_cond_br()) {
auto *cond = branchInst->get_operand(0);
auto *truebb = static_cast<BasicBlock *>(branchInst->get_operand(1));
auto *falsebb = static_cast<BasicBlock *>(branchInst->get_operand(2));
load_to_greg(cond, Reg::t(0));
// FIXME: Acutually this instruction is not necessary since
// load will sign extend the value
append_inst("bstrpick.d $t0, $t0, 0, 0");
append_inst("bne $t0, $zero, " + label_name(truebb));
append_inst("b " + label_name(falsebb));
} 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() {
load_to_freg(context.inst->get_operand(0), FReg::ft(0));
load_to_freg(context.inst->get_operand(1), FReg::ft(1));
switch (context.inst->get_instr_type()) {
case Instruction::fadd:
output.emplace_back("fadd.s $ft2, $ft0, $ft1");
break;
case Instruction::fsub:
output.emplace_back("fsub.s $ft2, $ft0, $ft1");
break;
case Instruction::fmul:
output.emplace_back("fmul.s $ft2, $ft0, $ft1");
break;
case Instruction::fdiv:
output.emplace_back("fdiv.s $ft2, $ft0, $ft1");
break;
default:
assert(false);
}
store_from_freg(context.inst, FReg::ft(2));
}
void CodeGen::gen_alloca() {
/* Current strategy: The allocated space is always after the
* pointer in the stack, so we can just add the size of the
* pointer to the offset.
* TODO: consider better strategy */
auto size = static_cast<int>(
context.inst->get_type()->get_pointer_element_type()->get_size());
auto offset = context.offset_map.at(context.inst);
auto position = offset - size;
if (IS_IMM_12(position))
append_inst("addi.d $t0, $fp, " + std::to_string(position));
else {
load_large_int32(position, Reg::t(0));
append_inst("add.d $t0, $fp, $t0");
}
store_from_greg(context.inst, Reg::t(0));
// append_inst("st.d $t0, $fp, " + std::to_string(offset));
}
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 {
if (type->is_int1_type()) {
append_inst("ld.b $t0, $t0, 0");
} else if (type->is_int32_type()) {
append_inst("ld.w $t0, $t0, 0");
} else { // Pointer
append_inst("ld.d $t0, $t0, 0");
}
store_from_greg(context.inst, Reg::t(0));
}
}
void CodeGen::gen_store() {
auto *ptr = context.inst->get_operand(1);
load_to_greg(ptr, Reg::t(0));
auto *v = context.inst->get_operand(0);
if (v->get_type()->is_float_type()) {
load_to_freg(v, FReg::ft(0));
append_inst("fst.s $ft0, $t0, 0");
} else {
load_to_greg(v, Reg::t(1));
if (v->get_type()->is_int1_type()) {
append_inst("st.b $t1, $t0, 0");
} else if (v->get_type()->is_int32_type()) {
append_inst("st.w $t1, $t0, 0");
} else { // Pointer
append_inst("st.d $t1, $t0, 0");
}
}
}
void CodeGen::gen_icmp() {
// CAUTION: only slt is available
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::ge:
// t0 >= t1 <=> !(t0 < t1) <=> (t0 < t1) xor 1
append_inst("slt $t2, $t0, $t1");
append_inst("xori $t2, $t2, 1");
break;
case Instruction::gt:
// t0 > t1 <=> t1 < t0
append_inst("slt $t2, $t1, $t0");
break;
case Instruction::le:
// t0 <= t1 <=> !(t1 < t0) <=> (t1 < t0) xor 1
append_inst("slt $t2, $t1, $t0");
append_inst("xori $t2, $t2, 1");
break;
case Instruction::lt:
// t0 < t1
append_inst("slt $t2, $t0, $t1");
break;
case Instruction::eq:
// t0 == t1 <=> (t0 xor t1) == 0 <=> (unsigned)(t0 xor t1) <
// 1
append_inst("xor $t2, $t0, $t1");
append_inst("sltui $t2, $t2, 1");
break;
case Instruction::ne:
// t0 != t1 <=> (t0 xor t1) != 0 <=> (unsigned)(t0 xor t1) >
// 0
append_inst("xor $t2, $t0, $t1");
append_inst("sltu $t2, $zero, $t2");
break;
default:
assert(false);
}
store_from_greg(context.inst, Reg::t(2));
}
void CodeGen::gen_fcmp() {
load_to_freg(context.inst->get_operand(0), FReg::ft(0));
load_to_freg(context.inst->get_operand(1), FReg::ft(1));
switch (context.inst->get_instr_type()) {
case Instruction::fge:
append_inst("fcmp.sle.s $fcc0, $ft1, $ft0");
break;
case Instruction::fgt:
append_inst("fcmp.slt.s $fcc0, $ft1, $ft0");
break;
case Instruction::fle:
append_inst("fcmp.sle.s $fcc0, $ft0, $ft1");
break;
case Instruction::flt:
append_inst("fcmp.slt.s $fcc0, $ft0, $ft1");
break;
case Instruction::feq:
append_inst("fcmp.seq.s $fcc0, $ft0, $ft1");
break;
case Instruction::fne:
append_inst("fcmp.sne.s $fcc0, $ft0, $ft1");
break;
default:
assert(false);
}
// Branch on FP Condition
append_inst("addi.w $t0, $zero, 1");
auto label = fcmp_label_name(context.bb, context.fcmp_cnt++);
append_inst("bcnez $fcc0, " + label);
append_inst("addi.w $t0, $zero, 0");
append_inst(label, ASMInstruction::Label);
store_from_greg(context.inst, Reg::t(0));
}
void CodeGen::gen_zext() {
auto *source = context.inst->get_operand(0);
auto bits = static_cast<IntegerType *>(source->get_type())->get_num_bits();
load_to_greg(source, Reg::t(0));
// FIXME: Acutually this instruction is not necessary
append_inst("bstrpick.w $t0, $t0, " + std::to_string(bits - 1) + ", 0");
store_from_greg(context.inst, Reg::t(0));
}
void CodeGen::gen_call() {
auto operands = context.inst->get_operands();
auto *func = static_cast<Function *>(operands[0]);
// 把参数放进 a 或 fa 寄存器
// 注意我们只允许至多八个整形和至多八个浮点参数
auto n = operands.size();
int garg_cnt = 0;
int farg_cnt = 0;
for (size_t i = 1; i < n; ++i) {
auto *arg = operands[i];
if (arg->get_type()->is_float_type()) {
load_to_freg(arg, FReg::fa(farg_cnt++));
} else { // int or pointer
load_to_greg(arg, Reg::a(garg_cnt++));
}
}
append_inst("bl " + func->get_name());
if (not func->get_return_type()->is_void_type()) {
if (func->get_return_type()->is_float_type()) {
store_from_freg(context.inst, FReg::fa(0));
} else {
store_from_greg(context.inst, Reg::a(0));
}
}
}
/*
* %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() {
auto *ptr = context.inst->get_operand(0);
load_to_greg(ptr, Reg::t(0));
// 这时 $t0 里应该是数组的起始地址
auto *type = ptr->get_type()->get_pointer_element_type(); // [10 x i32]
auto operands = context.inst->get_operands();
auto n = operands.size();
for (size_t i = 1; i < n; ++i) {
// $t1 里是各偏移量
load_to_greg(operands[i], Reg::t(1));
auto size = type->get_size();
// $t0 += index * size
if (IS_IMM_12(static_cast<int>(size))) {
append_inst("addi.d $t2, $zero, " + std::to_string(size));
} else {
load_large_int64(static_cast<int64_t>(size), Reg::t(2));
}
append_inst("mul.d $t1, $t1, $t2");
append_inst("add.d $t0, $t0, $t1");
if (type->is_array_type()) {
type = type->get_array_element_type(); // 1st it: type
// <- i32
} else if (type->is_pointer_type()) {
type = type->get_pointer_element_type();
}
}
store_from_greg(context.inst, Reg::t(0));
}
void CodeGen::gen_sitofp() {
auto *operand = context.inst->get_operand(0);
load_to_greg(operand, Reg::t(0));
append_inst("movgr2fr.w $ft0, $t0");
append_inst("ffint.s.w $ft0, $ft0");
store_from_freg(context.inst, FReg::ft(0));
}
void CodeGen::gen_fptosi() {
// The LLVM IR fptosi uses round-to-zero mode
auto *operand = context.inst->get_operand(0);
load_to_freg(operand, FReg::ft(0));
append_inst("ftintrz.w.s $ft0, $ft0");
append_inst("movfr2gr.s $t0, $ft0");
store_from_greg(context.inst, Reg::t(0));
}
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;
}
\ No newline at end of file
#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);
}
#!/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"] = -24; // TODO: 请填空
offset_map["array"] = -64; // 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"] = -72; // TODO: 请填空
// 获得数组的地址, 将其写入 $t0 中
codegen->append_inst("ld.d",
{"$t0", "$fp", std::to_string(offset_map["%op0"])});
// TODO: 计算 %op1 的值, 并将其写入 %op1 对应的内存空间中
codegen->append_inst("addi.d $t0, $t0, 0");
codegen->append_inst("st.d",
{"$t0", "$fp", std::to_string(offset_map["%op1"])});
/* 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"] = -80; // TODO: 请填空
// 获得数组的地址, 将其写入 $t0 中
codegen->append_inst("ld.d",
{"$t0", "$fp", std::to_string(offset_map["%op0"])});
// TODO: 计算 gep 的值, 并将其写入 %op2 对应的内存空间中
codegen->append_inst("addi.d $t0, $t0, 4");
codegen->append_inst("st.d",
{"$t0", "$fp", std::to_string(offset_map["%op2"])});
/* %op3 = load i32, i32* %op1 */
codegen->append_inst("%op3 = load i32, i32* %op1", ASMInstruction::Comment);
// 将 %op1 指向的空间中存储的值写入 %op3 对应的内存空间中
offset_map["%op3"] = -84; // TODO: 请填空
// TODO: 先获得 %op1 的值, 然后获得 %op1 指向的空间的值, 最后将这个值写入
// %op3 对应的内存空间中
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["%op3"])});
/* %op4 = mul i32 %op3, 3 */
codegen->append_inst("%op4 = mul i32 %op3, 3", ASMInstruction::Comment);
offset_map["%op4"] = -88; // TODO: 请填空
// TODO: 先获得 %op3 的值, 然后将其乘以 3, 最后将结果写入 %op4 对应的内存空
// 间中
codegen->append_inst("ld.w",
{"$t0", "$fp", std::to_string(offset_map["%op3"])});
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["%op4"])});
/* store i32 %op4, i32* %op2 */
codegen->append_inst("store i32 %op4, i32* %op2", ASMInstruction::Comment);
// 将 %op4 的值写入 %op2 指向的空间中
// TODO: 先获得 %op4 的值, 然后将其写入 %op2 指向的空间中
codegen->append_inst("ld.w",
{"$t0", "$fp", std::to_string(offset_map["%op4"])});
codegen->append_inst("ld.d",
{"$t1", "$fp", std::to_string(offset_map["%op2"])});
codegen->append_inst("st.w $t0, $t1, 0");
/* %op5 = load i32, i32* %op2 */
// 将 %op2 指向的空间中存储的值写入 %op5 对应的内存空间中
offset_map["%op5"] = -92; // TODO: 请填空
// TODO: 先获得 %op2 的值, 然后获得 %op2 指向的空间的值, 最后将这个值写入
// %op5 对应的内存空间中
codegen->append_inst("ld.d",
{"$t0", "$fp", std::to_string(offset_map["%op2"])});
codegen->append_inst("ld.w $t1, $t0, 0");
codegen->append_inst("st.w",
{"$t1", "$fp", std::to_string(offset_map["%op5"])});
/* ret i32 %op5 */
codegen->append_inst("ret i32 %op5", ASMInstruction::Comment);
// TODO: 将 %op5 的值写入 $a0 中
codegen->append_inst("ld.w",
{"$a0", "$fp", std::to_string(offset_map["%op5"])});
// 思考: 为什么不在这里 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"] = -17; // TODO: 请填空
// TODO: 将 5.5 (0x40b00000) 加载到浮点寄存器中
codegen->append_inst("lu12i.w $t0, 0x40b00");
codegen->append_inst("movgr2fr.w $ft0, $t0");
// TODO: 将 1.0 (0x3f800000) 加载到浮点寄存器中
codegen->append_inst("lu12i.w $t0, 0x3f80");
codegen->append_inst("movgr2fr.w $ft1, $t0");
// TODO: 使用 fcmp.slt.s 进行比较, 比较结果在浮点标志寄存器中, 你需要思考
// 如何将浮点标志寄存器中的值写入内存. 提示: 尝试使用 bcnez 指令
codegen->append_inst("fcmp.slt.s $fcc0, $ft1, $ft0");
codegen->append_inst("addi.w $t0, $zero, 1");
codegen->append_inst("bcnez $fcc0, .main_label_entry_fcmp_0");
codegen->append_inst("addi.w $t0, $zero, 0");
codegen->append_inst(".main_label_entry_fcmp_0", ASMInstruction::Label);
codegen->append_inst("st.b",
{"$t0", "$fp", std::to_string(offset_map["%op0"])});
/* %op1 = zext i1 %op0 to i32 */
codegen->append_inst("%op1 = zext i1 %op0 to i32", ASMInstruction::Comment);
// 将 %op0 的值从 i1 类型转换为 i32 类型, 并将结果写入到 %op1 对应的内存空
// 间中
offset_map["%op1"] = -21; // TODO: 请填空
// TODO: 获得 %op0 的值, 然后进行转换, 最后将结果写入 %op1
// 思考: 怎么转换? 需不需要显式地使用某些指令转换?
codegen->append_inst("ld.b",
{"$t0", "$fp", std::to_string(offset_map["%op0"])});
codegen->append_inst("st.w",
{"$t0", "$fp", std::to_string(offset_map["%op1"])});
/* %op2 = icmp ne i32 %op1, 0 */
codegen->append_inst("%op2 = icmp ne i32 %op1, 0", ASMInstruction::Comment);
// 比较 %op1 和 0, 并将结果写入 %op2 对应的内存空间中
offset_map["%op2"] = -22; // TODO: 请填空
// TODO: 获得 %op1 的值, 然后进行比较, 最后将结果写入 %op2
// 思考: 如何比较? 能否不使用跳转指令计算结果?
// 提示: 尝试使用 xor/xori 和 slt/sltu/slti/sltui 计算比较结果
codegen->append_inst("ld.w",
{"$t0", "$fp", std::to_string(offset_map["%op1"])});
codegen->append_inst("xori $t0, $t0, 0");
codegen->append_inst("sltu $t0, $zero, $t0");
codegen->append_inst("st.b",
{"$t0", "$fp", std::to_string(offset_map["%op2"])});
/* 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("ld.b",
{"$t0", "$fp", std::to_string(offset_map["%op2"])});
codegen->append_inst("bne $t0, $zero, .main_label3");
codegen->append_inst("b .main_label4");
/* 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"] = -24; // TODO: 请填空
offset_map["*%op0"] = -28; // 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("lu12i.w $t1, 0x4048f");
codegen->append_inst("ori $t1, $t1, 0x5c3");
// TODO: 将通用寄存器或者浮点寄存器中的值写入 %op0 对应的内存空间中
codegen->append_inst("st.w $t1, $t0, 0");
/* %op1 = load float, float* %op0 */
codegen->append_inst("%op1 = load float, float* %op0",
ASMInstruction::Comment);
// TODO: 先获得 %op0 的值, 然后获得 %op0 指向的空间的值, 最后将这个值写入
// %op1 对应的内存空间中
offset_map["%op1"] = -32; // TODO: 请填空
codegen->append_inst("ld.d",
{"$t0", "$fp", std::to_string(offset_map["%op0"])});
codegen->append_inst("fld.s $ft0, $t0, 0");
codegen->append_inst("fst.s",
{"$ft0", "$fp", std::to_string(offset_map["%op1"])});
/* %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"] = -36; // TODO: 请填空
codegen->append_inst("fld.s",
{"$ft0", "$fp", std::to_string(offset_map["%op1"])});
codegen->append_inst("ftintrz.w.s $ft0, $ft0");
codegen->append_inst("fst.s",
{"$ft0", "$fp", std::to_string(offset_map["%op2"])});
/* ret i32 %op2 */
codegen->append_inst("ret i32 %op2", ASMInstruction::Comment);
// TODO: 将 %op2 的值写入 $a0 中
codegen->append_inst("ld.w",
{"$a0", "$fp", std::to_string(offset_map["%op2"])});
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"] = -20; // 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"] = -28; // TODO: 请填空
offset_map["*%op1"] = -32; // 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"] = -36; // 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"] = -40; // 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"] = -20; // TODO: 请填空
// TODO: 将参数写入参数寄存器
codegen->append_inst("addi.w $a0, $zero, 110");
// TODO: 调用 callee 函数
codegen->append_inst("bl callee");
// 将返回值写入 %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("la.local $t0, a");
// TODO: 将 10 写入 a 对应的内存空间中
codegen->append_inst("addi.w $t1, $zero, 10");
codegen->append_inst("st.w $t1, $t0, 0");
/* %op0 = load i32, i32* @a */
codegen->append_inst("%op0 = load i32, i32* @a", ASMInstruction::Comment);
// 将 a 的值写入 %op0 对应的内存空间中
offset_map["%op0"] = -20; // TODO: 请填空
// TODO: 获得 a 的地址, 并存储在 $t0 中
codegen->append_inst("la.local $t0, a");
// 将 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"] = -17; // TODO: 请填空
codegen->append_inst("addi.w $t0, $zero, 5");
codegen->append_inst("addi.w $t1, $zero, 1");
// TODO: 使用 slt 指令比较
codegen->append_inst("slt $t0, $t1, $t0");
codegen->append_inst("st.b",
{"$t0", "$fp", std::to_string(offset_map["%op0"])});
/* %op1 = zext i1 %op0 to i32 */
codegen->append_inst("%op1 = zext i1 %op0 to i32", ASMInstruction::Comment);
// 将 %op0 的值从 i1 类型转换为 i32 类型, 并将结果写入到 %op1 对应的内存空
// 间中
offset_map["%op1"] = -21; // TODO: 请填空
// TODO: 获得 %op0 的值, 然后进行转换, 最后将结果写入 %op1
// 思考: 怎么转换? 需不需要显式地使用某些指令转换?
codegen->append_inst("ld.b",
{"$t0", "$fp", std::to_string(offset_map["%op0"])});
codegen->append_inst("st.w",
{"$t0", "$fp", std::to_string(offset_map["%op1"])});
/* %op2 = icmp ne i32 %op1, 0 */
codegen->append_inst("%op2 = icmp ne i32 %op1, 0", ASMInstruction::Comment);
// 比较 %op1 和 0, 并将结果写入 %op2 对应的内存空间中
offset_map["%op2"] = -22; // TODO: 请填空
// TODO: 获得 %op1 的值, 然后进行比较, 最后将结果写入 %op2
// 思考: 如何比较? 能否不使用跳转指令计算结果?
// 提示: 尝试使用 xor/xori 和 slt/sltu/slti/sltui 计算比较结果
codegen->append_inst("ld.w",
{"$t0", "$fp", std::to_string(offset_map["%op1"])});
codegen->append_inst("xori $t0, $t0, 0");
codegen->append_inst("sltu $t0, $zero, $t0");
codegen->append_inst("st.b",
{"$t0", "$fp", std::to_string(offset_map["%op2"])});
/* 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("ld.b",
{"$t0", "$fp", std::to_string(offset_map["%op2"])});
codegen->append_inst("bne $t0, $zero, .main_label3");
codegen->append_inst("b .main_label4");
/* 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")
add_subdirectory("3-codegen/warmup")
\ No newline at end of file
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