Forked from 汪汪队立大功队 / wwdldg
Source project has a limited visibility.
lir.cpp 14.03 KiB
#include "asm.h"
std::string LIRPhysRegname_(int reg)
    switch (reg)
    case 1:
        return "r0";
    case 2:
        return "r1";
    case 3:
        return "r2";
    case 4:
        return "r3";
    case 5:
        return "r4";
    case 6:
        return "r5";
    case 7:
        return "r6";
    case 8:
        return "r7";
    case 9:
        return "r8";
    case 10:
        return "r9";
    case 11:
        return "r10";
    case 12:
        return "r11";
    case 13:
        return "ip";
    case 14:
        return "sp";
    case 15:
        return "lr";
    case 16:
        return "pc";
    default:
        break;
    return "";
std::string LIRPhysFRegname_(int reg)
    switch (reg)
    case -1:
        return "s0";
    case -2:
        return "s1";
    case -3:
        return "s2";
    case -4:
        return "s3";
    case -5:
        return "s4";
    case -6:
        return "s5";
    case -7:
        return "s6";
    case -8:
        return "s7";
    case -9:
        return "s8";
    case -10:
        return "s9";
    case -11:
        return "s10";
    case -12:
        return "s11";
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
case -13: return "s12"; case -14: return "s13"; case -15: return "s14"; case -16: return "s15"; case -17: return "s16"; case -18: return "s17"; case -19: return "s18"; case -20: return "s19"; case -21: return "s20"; case -22: return "s21"; case -23: return "s22"; case -24: return "s23"; case -25: return "s24"; case -26: return "s25"; case -27: return "s26"; case -28: return "s27"; case -29: return "s28"; case -30: return "s29"; case -31: return "s30"; case -32: return "s31"; default: break; } return ""; } const std::map<int, std::string> LIRPhysReg::name_ = {{1, "r0"}, {2, "r1"}, {3, "r2"}, {4, "r3"}, {5, "r4"}, {6, "r5"}, {7, "r6"}, {8, "r7"}, {9, "r8"}, {10, "r9"}, {11, "r10"}, {12, "r11"}, {13, "ip"}, {14, "sp"}, {15, "lr"}, {16, "pc"}}; const std::map<int, std::string> LIRPhysFReg::name_ = { {-1, "s0"}, {-2, "s1"}, {-3, "s2"}, {-4, "s3"}, {-5, "s4"}, {-6, "s5"}, {-7, "s6"}, {-8, "s7"}, {-9, "s8"}, {-10, "s9"}, {-11, "s10"}, {-12, "s11"}, {-13, "s12"}, {-14, "s13"}, {-15, "s14"}, {-16, "s15"}, {-17, "s16"}, {-18, "s17"}, {-19, "s18"}, {-20, "s19"}, {-21, "s20"}, {-22, "s21"}, {-23, "s22"}, {-24, "s23"}, {-25, "s24"}, {-26, "s25"}, {-27, "s26"}, {-28, "s27"}, {-29, "s28"}, {-30, "s29"}, {-31, "s30"}, {-32, "s31"}}; const std::map<LIRShift::LIRShiftTy, std::string> LIRShift::name_ = { {LIRShift::LSAsrTy, "asr"}, {LIRShift::LSLslTy, "lsl"}, {LIRShift::LSLsrTy, "lsr"}, {LIRShift::LSRorTy, "ror"}, }; const std::map<LIRInstruction::LIRInstTy, std::string> LIRInstruction::inst_name_ = {{LIRInstruction::LAddTy, "add"}, {LIRInstruction::LSubTy, "sub"}, {LIRInstruction::LRsbTy, "rsb"}, {LIRInstruction::LMulTy, "mul"}, {LIRInstruction::LMlaTy, "mla"}, {LIRInstruction::LMlsTy, "mls"}, {LIRInstruction::LSdivTy, "sdiv"}, {LIRInstruction::LUdivTy, "udiv"}, {LIRInstruction::LAndTy, "and"}, {LIRInstruction::LOrrTy, "orr"},
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
{LIRInstruction::LEorTy, "eor"}, {LIRInstruction::LLslTy, "lsl"}, {LIRInstruction::LLsrTy, "lsr"}, {LIRInstruction::LAsrTy, "asr"}, {LIRInstruction::LRorTy, "ror"}, {LIRInstruction::LBTy, "b"}, {LIRInstruction::LBlTy, "bl"}, {LIRInstruction::LBxTy, "bx"}, {LIRInstruction::LMovTy, "mov"}, {LIRInstruction::LVmovTy, "vmov"}, {LIRInstruction::LVmovf32Ty, "vmov.f32"}, {LIRInstruction::LMov32Ty, "mov32"}, {LIRInstruction::LLdrTy, "ldr"}, {LIRInstruction::LVldrTy, "vldr"}, {LIRInstruction::LStrTy, "str"}, {LIRInstruction::LVstrTy, "vstr"}, {LIRInstruction::LPushTy, "push"}, {LIRInstruction::LPopTy, "pop"}, {LIRInstruction::LVpushTy, "vpush"}, {LIRInstruction::LVpopTy, "vpop"}, {LIRInstruction::LCmpTy, "cmp"}, {LIRInstruction::LVcmpTy, "vcmp.f32"}, {LIRInstruction::LVaddTy, "vadd.f32"}, {LIRInstruction::LVsubTy, "vsub.f32"}, {LIRInstruction::LVdivTy, "vdiv.f32"}, {LIRInstruction::LVmulTy, "vmul.f32"}, {LIRInstruction::LVmlaTy, "vmla.f32"}, {LIRInstruction::LVmlsTy, "vmls.f32"}, {LIRInstruction::LVnegTy, "vneg.f32"}, {LIRInstruction::LVcvtFSTy, "vcvt.f32.s32"}, {LIRInstruction::LVcvtSFTy, "vcvt.s32.f32"}, {LIRInstruction::LVmrsTy, "vmrs"}}; const std::map<LIRInstruction::LIRCondTy, std::string> LIRInstruction::cond_name_ = { {LIRInstruction::LCondGT, "gt"}, {LIRInstruction::LCondGE, "ge"}, {LIRInstruction::LCondLT, "lt"}, {LIRInstruction::LCondLE, "le"}, {LIRInstruction::LCondHI, "hi"}, {LIRInstruction::LCondCS, "cs"}, {LIRInstruction::LCondCC, "cc"}, {LIRInstruction::LCondLS, "ls"}, {LIRInstruction::LCondEQ, "eq"}, {LIRInstruction::LCondNE, "ne"}, {LIRInstruction::LCondVC, "vc"}, {LIRInstruction::LCondVS, "vs"}, {LIRInstruction::LCondNone, ""}}; template <typename... Args> std::string strfmt(const std::string &format, Args... args) { int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; if (size_s <= 0) { throw std::runtime_error("Error during formatting."); } auto size = static_cast<size_t>(size_s); std::unique_ptr<char[]> buf(new char[size]); std::snprintf(buf.get(), size, format.c_str(), args...); return std::string(buf.get(), buf.get() + size - 1); } std::string beggr = "\t"; std::string middr = ",["; std::string middr_2 = ","; std::string middr_3 = " "; std::string middr_4 = "],"; std::string enddr = "]\n"; std::string enddr_2 = "]!\n"; std::string enddr_3 = "\n"; std::string enddr_4 = "}\n"; std::string LIRMovInst::print() { return beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + middr_3 + result_->print() + middr_2 + operands_[0]->print() + enddr_3; } std::string LIRConstant::print() { return "#" + std::to_string(value_);
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
} std::string LIRShift::print() { return name_.at(tid_) + " #" + std::to_string(amount_); } std::string LIRVirtReg::print() { return "v" + std::to_string(rid_); } std::string LIRPhysReg::print() { return name_.at(rid_); } std::string LIRVirtFReg::print() { return "x" + std::to_string(frid_); } std::string LIRPhysFReg::print() { return name_.at(frid_); } std::string LIRBInst::print() { return beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + middr_3 + static_cast<LIRLabel *>(operands_[0])->name_ + enddr_3; } std::string LIRBlInst::print() { return beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + middr_3 + static_cast<LIRLabel *>(operands_[0])->name_ + enddr_3; } std::string LIRBxInst::print() { return beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + middr_3 + operands_[0]->print() + enddr_3; } std::string LIRVmrsInst::print() { return beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + " APSR_nzcv, FPSCR\n"; } std::string LIRModule::print() { std::string ans = "\t.arch armv7-a\n" "\t.eabi_attribute 28, 1\n" "\t.eabi_attribute 20, 1\n" "\t.eabi_attribute 21, 1\n" "\t.eabi_attribute 23, 3\n" "\t.eabi_attribute 24, 1\n" "\t.eabi_attribute 25, 1\n" "\t.eabi_attribute 26, 2\n" "\t.eabi_attribute 30, 6\n" "\t.eabi_attribute 34, 1\n" "\t.eabi_attribute 18, 4\n" "\t.arm\n" "\t.cpu cortex-a15\n" "\t.fpu neon-vfpv4\n" "\t.macro mov32, reg, val\n" "\t\tmovw \\reg, #:lower16:\\val\n" "\t\tmovt \\reg, #:upper16:\\val\n" "\t.endm\n"; for (LIRGlobalVariable *gv : global_list_) { ans += gv->print(); } ans += "\t.text\n"; for (LIRFunction *f : function_list_) { ans += f->print(); } return ans; } std::string LIRGlobalVariable::print()
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
{ std::string ans = "\t.global " + name_ + enddr_3; if (tid_ == LDataTy) { ans += "\t.data\n"; } else { ans += "\t.bss\n"; } ans += "\t.align 2\n"; ans += "\t.type " + name_ + ", %object\n"; ans += name_ + ":\n"; for (LIRDataDef *dd : init_val_) { ans += dd->print(); } return ans; } std::string LIRDataDef::print() { std::string ans = beggr; if (tid_ == LWordTy) { ans += ".word "; } else { ans += ".zero "; } ans += strfmt("%u\n", expr_); return ans; } std::string LIRFunction::print() { std::string ans = "\t.global " + name_ + enddr_3 + name_ + ":\t\t\t@num_args_ = " + std::to_string(num_args_) + "; has_result_ = " + (has_result_ ? "true" : "false") + enddr_3; for (LIRBasicBlock *bb : basic_blocks_) { ans += bb->print(); } return ans; } std::string LIRBasicBlock::print() { std::string ans = name_ + ":\t\t\t@"; ans += "pre_bbs_ = "; std::string delim = ""; for (LIRBasicBlock *prebb : pre_bbs_) { ans += delim + prebb->name_; delim = ", "; } ans += "; succ_bbs_ = "; delim = ""; for (LIRBasicBlock *succbb : succ_bbs_) { ans += delim + succbb->name_; delim = ", "; } ans += ";\n"; for (LIRInstruction *inst : instr_list_) { ans += inst->print(); } return ans; } std::string LIRIntInst::print() { std::string ans = beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + middr_3; std::string delim = "";
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
if (result_ != nullptr) { ans += delim + result_->print(); delim = middr_2; } for (LIROperand *op : operands_) { ans += delim + op->print(); delim = middr_2; } ans += enddr_3; return ans; } std::string LIRFloatInst::print() { std::string ans = beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + middr_3; std::string delim = ""; if (result_ != nullptr) { ans += delim + result_->print(); delim = middr_2; } for (LIROperand *op : operands_) { ans += delim + op->print(); delim = middr_2; } ans += enddr_3; return ans; } std::string LIRVmovInst::print() { std::string ans = ""; LIROperand::LIROprTy result_tid = result_->tid_; LIROperand::LIROprTy op0_tid = operands_[0]->tid_; ans += beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + middr_3 + result_->print() + middr_2 + operands_[0]->print() + enddr_3; return ans; } std::string LIRVmovf32Inst::print() { std::string ans = beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + middr_3 + result_->print() + middr_2 + operands_[0]->print() + enddr_3; return ans; } std::string LIRMov32Inst::print() { std::string ans = beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + middr_3 + result_->print() + middr_2; if(dynamic_cast<LIRConstant*>(operands_[0])){ ans+=(operands_[0]->print()).substr(1,std::string::npos)+enddr_3; }else{ ans+=static_cast<LIRLabel*>(operands_[0])->name_+enddr_3; } return ans; } std::string LIRLdrInst::print() { std::string ans = beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + middr_3; ans += result_->print() + middr_2 + "["; std::string temp1 = operands_[0]->print(); std::string temp2 = operands_[1]->print(); if(addr_tid_==LRegisterOffsetTy){ ans += temp1 + middr_2 + temp2 + enddr; }else if(addr_tid_==LPreIndexedTy){ ans += temp1 +middr_2 + temp2 + enddr_2; }else { assert(addr_tid_==LPostIndexedTy);
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
ans += temp1 + middr_4 + temp2 + enddr_3; } return ans; } std::string LIRVldrInst::print() { std::string ans = beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + middr_3; ans += result_->print() + middr_2; std::string temp1 = operands_[0]->print(); std::string temp2 = operands_[1]->print(); ans+= "[" + temp1 +middr_2 + temp2 + enddr; return ans; } std::string LIRStrInst::print() { std::string ans = beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + middr_3; if (addr_tid_ == LRegisterOffsetTy) { ans += operands_[0]->print() + middr + operands_[1]->print() + middr_2 + operands_[2]->print() + enddr; } else if (addr_tid_ == LPreIndexedTy) { ans += operands_[0]->print() + middr + operands_[1]->print() + middr_2 + operands_[2]->print() + enddr_2; } else { ans += operands_[0]->print() + middr + operands_[1]->print() + middr_4 + operands_[2]->print() + enddr_3; } return ans; } std::string LIRVstrInst::print() { std::string ans = beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + middr_3; ans += operands_[0]->print() + middr + operands_[1]->print() + middr_2 + operands_[2]->print() + enddr; return ans; } std::string LIRPushInst::print() { std::string ans = beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + " {"; std::string delim = ""; for (LIROperand *op : operands_) { ans += delim + op->print(); delim = middr_2; } ans += enddr_4; return ans; } std::string LIRPopInst::print() { std::string ans = beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + " {"; std::string delim = ""; for (LIROperand *op : operands_) { ans += delim + op->print(); delim = middr_2; } ans += enddr_4; return ans; } std::string LIRVpushInst::print() { std::string ans = beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + " {"; std::string delim = ""; for (LIROperand *op : operands_)
491492493494495496497498499500501502503504505506507508509510
{ ans += delim + op->print(); delim = middr_2; } ans += enddr_4; return ans; } std::string LIRVpopInst::print() { std::string ans = beggr + inst_name_.at(op_id_) + cond_name_.at(cond_id_) + " {"; std::string delim = ""; for (LIROperand *op : operands_) { ans += delim + op->print(); delim = middr_2; } ans += enddr_4; return ans; }