291 lines
13 KiB
Rust
291 lines
13 KiB
Rust
// #[cfg(test)]
|
|
pub mod tests {
|
|
use std::{ fs::File, io::Write, vec };
|
|
|
|
use compiler::backend::*;
|
|
use var::*;
|
|
|
|
#[test]
|
|
pub fn quicksort_example() {
|
|
/* ---------- ---------- quicksort.part.0 ---------- ---------- */
|
|
let mut entry = Block::new("entry1".into());
|
|
let addispsp_32 = Inst::Add(AddInst::new(REG_SP.into(), REG_SP.into(), (-32).into()));
|
|
let sds18sp = Inst::Sd(SdInst::new(REG_S1.into(), (8).into(), REG_SP.into()));
|
|
let sds20sp = Inst::Sd(SdInst::new(REG_S2.into(), (0).into(), REG_SP.into()));
|
|
let sdra24sp = Inst::Sd(SdInst::new(REG_RA.into(), (24).into(), REG_SP.into()));
|
|
let sds016sp = Inst::Sd(SdInst::new(REG_S0.into(), (16).into(), REG_SP.into()));
|
|
let mvs1a0 = Inst::Mv(MvInst::new(REG_S1.into(), REG_A0.into()));
|
|
let mvs2a2 = Inst::Mv(MvInst::new(REG_S2.into(), REG_A2.into()));
|
|
entry.extend_insts(vec![addispsp_32, sds18sp, sds20sp, sdra24sp, sds016sp, mvs1a0, mvs2a2]);
|
|
|
|
let mut l14 = Block::new("L14".into());
|
|
let sllia5a12 = Inst::Sll(SllInst::new(REG_A5.into(), REG_A1.into(), (2).into()));
|
|
let adda5s1a5 = Inst::Add(AddInst::new(REG_A5.into(), REG_S1.into(), REG_A5.into()));
|
|
let lwa70a5 = Inst::Lw(LwInst::new(REG_A7.into(), (0).into(), REG_A5.into()));
|
|
let mva4s2 = Inst::Mv(MvInst::new(REG_A4.into(), REG_S2.into()));
|
|
let mva3a1 = Inst::Mv(MvInst::new(REG_A3.into(), REG_A1.into()));
|
|
let mvs0a1 = Inst::Mv(MvInst::new(REG_S0.into(), REG_A1.into()));
|
|
let bgea1s2l3 = Inst::Bge(BgeInst::new(REG_A1.into(), REG_S2.into(), "L3".into()));
|
|
l14.extend_insts(vec![sllia5a12, adda5s1a5, lwa70a5, mva4s2, mva3a1, mvs0a1, bgea1s2l3]);
|
|
|
|
let mut l2 = Block::new("L2".into());
|
|
let sllia5a42 = Inst::Sll(SllInst::new(REG_A5.into(), REG_A4.into(), (2).into()));
|
|
let adda5s1a5 = Inst::Add(AddInst::new(REG_A5.into(), REG_S1.into(), REG_A5.into()));
|
|
let jl11 = Inst::Jmp(JmpInst::new("L11".into()));
|
|
l2.extend_insts(vec![sllia5a42, adda5s1a5, jl11]);
|
|
|
|
let mut l5 = Block::new("L5".into());
|
|
// FIXME 这里应该要把 add 改成 addw
|
|
let addiw1414_1 = Inst::Add(AddInst::new(REG_A4.into(), REG_A4.into(), (-1).into()));
|
|
let beqa4a3l24 = Inst::Beq(BeqInst::new(REG_A4.into(), REG_A3.into(), "L24".into()));
|
|
l5.extend_insts(vec![addiw1414_1, beqa4a3l24]);
|
|
|
|
let mut l11 = Block::new("L11".into());
|
|
let lwa60a5 = Inst::Lw(LwInst::new(REG_A6.into(), (0).into(), REG_A5.into()));
|
|
let addia5a5_4 = Inst::Add(AddInst::new(REG_A5.into(), REG_A5.into(), (-4).into()));
|
|
let bgea6a7l5 = Inst::Bge(BgeInst::new(REG_A6.into(), REG_A7.into(), "L5".into()));
|
|
let sllia5a32 = Inst::Sll(SllInst::new(REG_A5.into(), REG_A3.into(), (2).into()));
|
|
let adda0s1a5 = Inst::Add(AddInst::new(REG_A0.into(), REG_S1.into(), REG_A5.into()));
|
|
let addiws0a31 = Inst::Add(AddInst::new(REG_S0.into(), REG_A3.into(), (1).into()));
|
|
let blea4a3l4 = Inst::Ble(BleInst::new(REG_A4.into(), REG_A3.into(), "L4".into()));
|
|
let sllit1a42 = Inst::Sll(SllInst::new(REG_T1.into(), REG_A4.into(), (2).into()));
|
|
let addt1s1t1 = Inst::Add(AddInst::new(REG_T1.into(), REG_S1.into(), REG_T1.into()));
|
|
let lwa30t1 = Inst::Lw(LwInst::new(REG_A3.into(), (0).into(), REG_T1.into()));
|
|
let swa30a0 = Inst::Sw(SwInst::new(REG_A3.into(), (0).into(), REG_A0.into()));
|
|
let blea4s0l26 = Inst::Ble(BleInst::new(REG_A4.into(), REG_S0.into(), "L26".into()));
|
|
let addia5a54 = Inst::Add(AddInst::new(REG_A5.into(), REG_A5.into(), (4).into()));
|
|
let adda5s1a5 = Inst::Add(AddInst::new(REG_A5.into(), REG_S1.into(), REG_A5.into()));
|
|
let jl7 = Inst::Jmp(JmpInst::new("L7".into()));
|
|
l11.extend_insts(
|
|
vec![
|
|
lwa60a5,
|
|
addia5a5_4,
|
|
bgea6a7l5,
|
|
sllia5a32,
|
|
adda0s1a5,
|
|
addiws0a31,
|
|
blea4a3l4,
|
|
sllit1a42,
|
|
addt1s1t1,
|
|
lwa30t1,
|
|
swa30a0,
|
|
blea4s0l26,
|
|
addia5a54,
|
|
adda5s1a5,
|
|
jl7
|
|
]
|
|
);
|
|
|
|
let mut l9 = Block::new("L9".into());
|
|
let addia5a54 = Inst::Add(AddInst::new(REG_A5.into(), REG_A5.into(), (4).into()));
|
|
let beqa4s0l27 = Inst::Beq(BeqInst::new(REG_A4.into(), REG_S0.into(), "L27".into()));
|
|
l9.extend_insts(vec![addia5a54, beqa4s0l27]);
|
|
|
|
let mut l7 = Block::new("L7".into());
|
|
let lwa60a5 = Inst::Lw(LwInst::new(REG_A6.into(), (0).into(), REG_A5.into()));
|
|
let mva3s0 = Inst::Mv(MvInst::new(REG_A3.into(), REG_S0.into()));
|
|
let addiws0s01 = Inst::Add(AddInst::new(REG_S0.into(), REG_S0.into(), (1).into()));
|
|
let blta6a7l9 = Inst::Blt(BltInst::new(REG_A6.into(), REG_A7.into(), "L9".into()));
|
|
let blea4a3l17 = Inst::Ble(BleInst::new(REG_A4.into(), REG_A3.into(), "L17".into()));
|
|
let swa60t1 = Inst::Sw(SwInst::new(REG_A6.into(), (0).into(), REG_T1.into()));
|
|
let addiwa4a4_1 = Inst::Add(AddInst::new(REG_A4.into(), REG_A4.into(), (-1).into()));
|
|
let bgta4a3l2 = Inst::Bgt(BgtInst::new(REG_A4.into(), REG_A3.into(), "L2".into()));
|
|
l7.extend_insts(
|
|
vec![
|
|
lwa60a5,
|
|
mva3s0,
|
|
addiws0s01,
|
|
blta6a7l9,
|
|
blea4a3l17,
|
|
swa60t1,
|
|
addiwa4a4_1,
|
|
bgta4a3l2
|
|
]
|
|
);
|
|
|
|
let mut l17 = Block::new("L17".into());
|
|
let mvs0a3 = Inst::Mv(MvInst::new(REG_S0.into(), REG_A3.into()));
|
|
let jl10 = Inst::Jmp(JmpInst::new("L10".into()));
|
|
l17.extend_insts(vec![mvs0a3, jl10]);
|
|
|
|
let mut l27 = Block::new("L27".into());
|
|
let siila5s02 = Inst::Sll(SllInst::new(REG_A5.into(), REG_S0.into(), (2).into()));
|
|
let adda5s1a5 = Inst::Add(AddInst::new(REG_A5.into(), REG_S1.into(), REG_A5.into()));
|
|
l27.extend_insts(vec![siila5s02, adda5s1a5]);
|
|
|
|
let mut l10 = Block::new("L10".into());
|
|
let swa70a5 = Inst::Sw(SwInst::new(REG_A7.into(), (0).into(), REG_A5.into()));
|
|
let addiwa2s0_1 = Inst::Add(AddInst::new(REG_A2.into(), REG_S0.into(), (-1).into()));
|
|
let bgea1a2l3 = Inst::Bge(BgeInst::new(REG_A1.into(), REG_A2.into(), "L3".into()));
|
|
let mva0s1 = Inst::Mv(MvInst::new(REG_A0.into(), REG_S1.into()));
|
|
let callQuickSortpart0 = Inst::Call(CallInst::new("QuickSort.part.0".into()));
|
|
l10.extend_insts(vec![swa70a5, addiwa2s0_1, bgea1a2l3, mva0s1, callQuickSortpart0]);
|
|
|
|
let mut l3 = Block::new("L3".into());
|
|
let addiwa1s01 = Inst::Add(AddInst::new(REG_A1.into(), REG_S0.into(), (1).into()));
|
|
let ldra24sp = Inst::Ld(LdInst::new(REG_RA.into(), (24).into(), REG_SP.into()));
|
|
let lds016sp = Inst::Ld(LdInst::new(REG_S0.into(), (16).into(), REG_SP.into()));
|
|
let lds18sp = Inst::Ld(LdInst::new(REG_S1.into(), (8).into(), REG_SP.into()));
|
|
let lds20sp = Inst::Ld(LdInst::new(REG_S2.into(), (0).into(), REG_SP.into()));
|
|
let addispsp32 = Inst::Add(AddInst::new(REG_SP.into(), REG_SP.into(), (32).into()));
|
|
let ret = Inst::Ret;
|
|
l3.extend_insts(vec![addiwa1s01, ldra24sp, lds016sp, lds18sp, lds20sp, addispsp32, ret]);
|
|
|
|
let mut l26 = Block::new("L26".into());
|
|
let mva3s0 = Inst::Mv(MvInst::new(REG_A3.into(), REG_S0.into()));
|
|
l26.extend_insts(vec![mva3s0]);
|
|
|
|
let mut l24 = Block::new("L24".into());
|
|
let sllia5a32 = Inst::Sll(SllInst::new(REG_A5.into(), REG_A3.into(), (2).into()));
|
|
l24.extend_insts(vec![sllia5a32]);
|
|
|
|
let mut l4 = Block::new("L4".into());
|
|
let adda5s1a5 = Inst::Add(AddInst::new(REG_A5.into(), REG_S1.into(), REG_A5.into()));
|
|
let mvs0a3 = Inst::Mv(MvInst::new(REG_S0.into(), REG_A3.into()));
|
|
let jl10 = Inst::Jmp(JmpInst::new("L10".into()));
|
|
l4.extend_insts(vec![adda5s1a5, mvs0a3, jl10]);
|
|
|
|
let mut QuickSortPart0 = Func::new("QuickSort.part.0".into(), Vec::new(), entry);
|
|
QuickSortPart0.push_bb(l14);
|
|
QuickSortPart0.push_bb(l2);
|
|
QuickSortPart0.push_bb(l5);
|
|
QuickSortPart0.push_bb(l11);
|
|
QuickSortPart0.push_bb(l9);
|
|
QuickSortPart0.push_bb(l7);
|
|
QuickSortPart0.push_bb(l17);
|
|
QuickSortPart0.push_bb(l27);
|
|
QuickSortPart0.push_bb(l10);
|
|
QuickSortPart0.push_bb(l3);
|
|
QuickSortPart0.push_bb(l26);
|
|
QuickSortPart0.push_bb(l24);
|
|
QuickSortPart0.push_bb(l4);
|
|
|
|
/* ---------- ---------- quicksort ---------- ---------- */
|
|
let mut entry = Block::new("entry2".into());
|
|
let bgea1a2l31 = Inst::Bge(BgeInst::new(REG_A1.into(), REG_A2.into(), "L31".into()));
|
|
let addispsp_16 = Inst::Add(AddInst::new(REG_SP.into(), REG_SP.into(), (-16).into()));
|
|
let sdra8sp = Inst::Sd(SdInst::new(REG_RA.into(), (8).into(), REG_SP.into()));
|
|
let callQuickSortpart0 = Inst::Call(CallInst::new("QuickSort.part.0".into()));
|
|
let ldra8sp = Inst::Ld(LdInst::new(REG_RA.into(), (8).into(), REG_SP.into()));
|
|
let lia00 = Inst::Li(LiInst::new(REG_A0.into(), (0).into()));
|
|
let addispsp16 = Inst::Add(AddInst::new(REG_SP.into(), REG_SP.into(), (16).into()));
|
|
let ret = Inst::Ret;
|
|
entry.extend_insts(
|
|
vec![
|
|
bgea1a2l31,
|
|
addispsp_16,
|
|
sdra8sp,
|
|
callQuickSortpart0,
|
|
ldra8sp,
|
|
lia00,
|
|
addispsp16,
|
|
ret
|
|
]
|
|
);
|
|
|
|
let mut l31 = Block::new("L31".into());
|
|
let lia00 = Inst::Li(LiInst::new(REG_A0.into(), (0).into()));
|
|
let ret = Inst::Ret;
|
|
l31.extend_insts(vec![lia00, ret]);
|
|
|
|
let mut QuickSort = Func::new("QuickSort".into(), Vec::new(), entry);
|
|
QuickSort.push_bb(l31);
|
|
|
|
/* ---------- ---------- main ---------- ---------- */
|
|
let mut entry = Block::new("entry3".into());
|
|
let addispsp_32 = Inst::Add(AddInst::new(REG_SP.into(), REG_SP.into(), (-32).into()));
|
|
let lia29 = Inst::Li(LiInst::new(REG_A2.into(), (9).into()));
|
|
let lia10 = Inst::Li(LiInst::new(REG_A1.into(), (10).into()));
|
|
let llas0arr1 = Inst::La(LaInst::new(REG_S0.into(), "arr".into()));
|
|
let sds016sp = Inst::Sd(SdInst::new(REG_S0.into(), (16).into(), REG_SP.into()));
|
|
let sds18sp = Inst::Sd(SdInst::new(REG_S1.into(), (8).into(), REG_SP.into()));
|
|
let sdra24sp = Inst::Sd(SdInst::new(REG_RA.into(), (24).into(), REG_SP.into()));
|
|
let llas0arr2 = Inst::La(LaInst::new(REG_S0.into(), "arr".into()));
|
|
let callQuickSortPart0 = Inst::Call(CallInst::new("QuickSort.part.0".into()));
|
|
// FIXME 这里可能 arr + 40 不能汇编过
|
|
let llas1arr40 = Inst::La(LaInst::new(REG_S1.into(), "arr+40".into()));
|
|
entry.extend_insts(
|
|
vec![
|
|
addispsp_32,
|
|
lia29,
|
|
lia10,
|
|
llas0arr1,
|
|
sds016sp,
|
|
sds18sp,
|
|
sdra24sp,
|
|
llas0arr2,
|
|
callQuickSortPart0,
|
|
llas1arr40
|
|
]
|
|
);
|
|
|
|
let mut l35 = Block::new("L35".into());
|
|
let lwa10s0 = Inst::Lw(LwInst::new(REG_A1.into(), (0).into(), REG_S0.into()));
|
|
// FIXME lc0 是 .string
|
|
let llaa0lc0 = Inst::La(LaInst::new(REG_A0.into(), "LC0".into()));
|
|
let addis0s04 = Inst::Add(AddInst::new(REG_S0.into(), REG_S0.into(), (4).into()));
|
|
let callprintf = Inst::Call(CallInst::new("printf@plt".into()));
|
|
let bnes0s1l35 = Inst::Bne(BneInst::new(REG_S0.into(), REG_S1.into(), "L35".into()));
|
|
let ldra24sp = Inst::Ld(LdInst::new(REG_RA.into(), (24).into(), REG_SP.into()));
|
|
let lds016sp = Inst::Ld(LdInst::new(REG_S0.into(), (16).into(), REG_SP.into()));
|
|
let lds18sp = Inst::Ld(LdInst::new(REG_S1.into(), (8).into(), REG_SP.into()));
|
|
let lia00 = Inst::Li(LiInst::new(REG_A0.into(), (0).into()));
|
|
let addispsp32 = Inst::Add(AddInst::new(REG_SP.into(), REG_SP.into(), (32).into()));
|
|
let ret = Inst::Ret;
|
|
l35.extend_insts(
|
|
vec![
|
|
lwa10s0,
|
|
llaa0lc0,
|
|
addis0s04,
|
|
callprintf,
|
|
bnes0s1l35,
|
|
ldra24sp,
|
|
lds016sp,
|
|
lds18sp,
|
|
lia00,
|
|
addispsp32,
|
|
ret
|
|
]
|
|
);
|
|
|
|
let mut main = Func::new("main".into(), Vec::new(), entry);
|
|
main.push_bb(l35);
|
|
|
|
let arr = Var::IntArr(ArrVar {
|
|
name: "arr".into(),
|
|
capacity: 10,
|
|
init: vec![
|
|
(0, 4),
|
|
(1, 3),
|
|
(2, 9),
|
|
(3, 2),
|
|
(4, 0),
|
|
(5, 1),
|
|
(6, 6),
|
|
(7, 5),
|
|
(8, 7),
|
|
(9, 8)
|
|
],
|
|
is_const: false,
|
|
});
|
|
|
|
let lc0 = Var::Str(Str {
|
|
name: "LC0".into(),
|
|
init: Some(" %d\\n".into()),
|
|
is_const: true,
|
|
});
|
|
|
|
let module = Module {
|
|
name: "qs.into()".into(),
|
|
global: vec![arr, lc0],
|
|
funcs: vec![QuickSortPart0, QuickSort, main],
|
|
entry: Some("main".into()),
|
|
};
|
|
|
|
let asm = module.gen_asm();
|
|
|
|
let mut file = File::create("output/qs.s").unwrap();
|
|
file.write_all(asm.as_bytes());
|
|
}
|
|
}
|