export.rs 22.72 KiB
use std::{fmt::{Display, Debug}, collections::HashMap};
use crate::ctype::Linkage;
use super::{GPOperand, RVGPR, MachineProgram, RV64Instruction, DataLiteral, AsmGlobalObject, FPOperand, RVFPR, OperandBase};
impl Display for MachineProgram {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        self.print(f)
impl MachineProgram {
    pub fn print(&self, writer: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        writeln!(writer, "# Built-in library")?;
        let builtin = include_str!("../rt/builtin.S");
        writeln!(writer, "{}", builtin)?;
        let mut counter = 0;
        let mut bb_names = HashMap::new();
        let mut funcs = self.funcs.iter().collect::<Vec<_>>();
        funcs.sort_by_key(|(name, _)| *name);
        for (_, f) in funcs {
            counter += 1;
            let mut counter2 = 0;
            let mut count2 = || {
                counter2 += 1;
                counter2
            writeln!(writer, "\t.section\t.text")?;
            writeln!(writer, "\t.align\t4")?;
            writeln!(writer, "\t.globl\t{}", f.func)?;
            writeln!(writer, "\t.type\t{}, @function", f.func)?;
            writeln!(writer, "{}:", f.func)?;
            for bb in f.bbs.iter() {
                let mbb = &self.blocks[*bb];
                bb_names.insert(*bb, format!(".LBB{}_{}.{}", counter, count2(), mbb.name));
            let bbs = f.bbs.clone();
            for i in 0..bbs.len() {
                let bb = bbs[i];
                let next_bb = bbs.get(i + 1);
                if i != 0 {
                    writeln!(writer, "{}:", bb_names[&bb])?;
                let mut iter = self.blocks[bb].insts_head;
                while let Some(inst_id) = iter {
                    let inst = self.insts[inst_id].clone();
                    iter = inst.next;
                    if matches!(inst.inst, RV64Instruction::NOP) {
                        continue;
                    let cond = match inst.inst {
                        RV64Instruction::JEQ { rs1, rs2, succ, fail } =>
                            Some(("eq", rs1, rs2, succ, fail)),
                        RV64Instruction::JNE { rs1, rs2, succ, fail } =>
                            Some(("ne", rs1, rs2, succ, fail)),
                        RV64Instruction::JLT { rs1, rs2, succ, fail } =>
                            Some(("lt", rs1, rs2, succ, fail)),
                        RV64Instruction::JGE { rs1, rs2, succ, fail } =>
                            Some(("ge", rs1, rs2, succ, fail)),
                        RV64Instruction::JLTU { rs1, rs2, succ, fail } =>