fix(backend): 修正后端部分代码

master
李仁哲 1 month ago
parent e75efa940c
commit ed4ec6d742

@ -37,15 +37,6 @@ impl Display for PReg {
let str = match self.kind() {
RegKind::Address => match self.num() {
0 => "x0",
1 => "x1",
2 => "x2",
3 => "x3",
4 => "x4",
5 => "x5",
6 => "x6",
7 => "x7",
8 => "x8",
9 => "x9",
10 => "x10",
11 => "x11",
12 => "x12",
@ -54,33 +45,12 @@ impl Display for PReg {
15 => "x15",
16 => "x16",
17 => "x17",
18 => "x18",
19 => "x19",
20 => "x20",
21 => "x21",
22 => "x22",
23 => "x23",
24 => "x24",
25 => "x25",
26 => "x26",
27 => "x27",
28 => "x28",
29 => "fp",
30 => "x30",
31 => "sp",
32 => "xzr",
_ => "<invalid>",
},
RegKind::Integer => match self.num() {
0 => "w0",
1 => "w1",
2 => "w2",
3 => "w3",
4 => "w4",
5 => "w5",
6 => "w6",
7 => "w7",
8 => "w8",
9 => "w9",
10 => "w10",
11 => "w11",
@ -90,24 +60,10 @@ impl Display for PReg {
15 => "w15",
16 => "w16",
17 => "w17",
18 => "w18",
19 => "w19",
20 => "w20",
21 => "w21",
22 => "w22",
23 => "w23",
24 => "w24",
25 => "w25",
26 => "w26",
27 => "w27",
28 => "w28",
29 => "fp",
30 => "w30",
31 => "sp",
32 => "wzr",
_ => "invalid",
}
_ => "invalid"
};
asm += str.to_string().as_str();
asm

@ -78,35 +78,6 @@ impl MirFunction {
pub fn add_storage_stack_size(self, ctx: &mut MirContext, size: i32) {
self.deref_mut(ctx).expect("Invalid Function Pointer").storage_stack_size += size;
}
pub fn add_calleeargs_stack_size(self, ctx: &mut MirContext, size: i32) {
self.deref_mut(ctx).expect("Invalid Function Pointer").calleeargs_stack_size += size;
}
pub fn calleeargs_stack_size(self, ctx: &MirContext) -> i32 {
self.deref(ctx).expect("Invalid Function Pointer").calleeargs_stack_size
}
pub fn callee_regs(self, ctx: &MirContext) -> Vec<PReg> {
let mut regs: Vec<PReg> = self.deref(ctx).expect("Invalid Function Pointer").callee_regs.iter().copied().collect();
regs.sort();
regs
}
pub fn add_callee_reg(self, ctx: &mut MirContext, reg: PReg) {
self.deref_mut(ctx).expect("Invalid Function Pointer").callee_regs.insert(reg);
}
pub fn callee_stack_size(self, ctx: &MirContext) -> i32 {
let mut size = 0;
for _reg in self.callee_regs(ctx) {
size += 8;
}
if size % 8 != 0 {
size += 4;
}
size
}
}
impl ArenaPtr for MirFunction {

@ -37,15 +37,6 @@ impl Reg {
}
}
pub fn is_caller_saved(&self) -> bool {
match self {
Reg::P(preg) => {
preg.is_callee_saved()
}
Reg::V(_) => false,
}
}
}
// 手动实现PartialEq和Eq
@ -89,7 +80,6 @@ impl std::hash::Hash for Reg {
p.0.hash(state);
}
Reg::V(v) => {
// 虚拟寄存器单独哈希域
2u8.hash(state);
v.0.hash(state);
}
@ -118,11 +108,8 @@ impl PReg {
_ => false,
}
}
pub fn hw_index(&self) -> u8 { self.0}
pub fn is_callee_saved(&self) -> bool { CALLEE_SAVED_REGS.contains(self) }
pub fn is_caller_saved(&self) -> bool { CALLER_SAVED_REGS.contains(self) }
}
@ -149,14 +136,6 @@ impl From<PReg> for Reg {
// ARMV8-A64地址寄存器
pub const fn x_reg(index: u8) -> PReg { PReg::new(index, RegKind::Address) }
pub const fn x0() -> PReg { PReg::new(0, RegKind::Address) }
pub const fn x1() -> PReg { PReg::new(1, RegKind::Address) }
pub const fn x2() -> PReg { PReg::new(2, RegKind::Address) }
pub const fn x3() -> PReg { PReg::new(3, RegKind::Address) }
pub const fn x4() -> PReg { PReg::new(4, RegKind::Address) }
pub const fn x5() -> PReg { PReg::new(5, RegKind::Address) }
pub const fn x6() -> PReg { PReg::new(6, RegKind::Address) }
pub const fn x7() -> PReg { PReg::new(7, RegKind::Address) }
pub const fn x8() -> PReg { PReg::new(8, RegKind::Address) }
pub const fn x9() -> PReg { PReg::new(9, RegKind::Address) }
pub const fn x10() -> PReg { PReg::new(10, RegKind::Address) }
pub const fn x11() -> PReg { PReg::new(11, RegKind::Address) }
@ -166,33 +145,11 @@ pub const fn x14() -> PReg { PReg::new(14, RegKind::Address) }
pub const fn x15() -> PReg { PReg::new(15, RegKind::Address) }
pub const fn x16() -> PReg { PReg::new(16, RegKind::Address) }
pub const fn x17() -> PReg { PReg::new(17, RegKind::Address) }
pub const fn x18() -> PReg { PReg::new(18, RegKind::Address) }
pub const fn x19() -> PReg { PReg::new(19, RegKind::Address) }
pub const fn x20() -> PReg { PReg::new(20, RegKind::Address) }
pub const fn x21() -> PReg { PReg::new(21, RegKind::Address) }
pub const fn x22() -> PReg { PReg::new(22, RegKind::Address) }
pub const fn x23() -> PReg { PReg::new(23, RegKind::Address) }
pub const fn x24() -> PReg { PReg::new(24, RegKind::Address) }
pub const fn x25() -> PReg { PReg::new(25, RegKind::Address) }
pub const fn x26() -> PReg { PReg::new(26, RegKind::Address) }
pub const fn x27() -> PReg { PReg::new(27, RegKind::Address) }
pub const fn x28() -> PReg { PReg::new(28, RegKind::Address) }
pub const fn fp() -> PReg { PReg::new(29, RegKind::Address) }
pub const fn x30() -> PReg { PReg::new(30, RegKind::Address) }
pub const fn sp() -> PReg { PReg::new(31, RegKind::Address) }
pub const fn xzr() -> PReg { PReg::new(32, RegKind::Address) }
pub const fn bzw() -> PReg { PReg::new(33, RegKind::Integer)}
// ARMV8-A64整数寄存器
pub const fn w_reg(index: u8) -> PReg { PReg::new(index, RegKind::Integer) }
pub const fn w0() -> PReg { PReg::new(0, RegKind::Integer) }
pub const fn w1() -> PReg { PReg::new(1, RegKind::Integer) }
pub const fn w2() -> PReg { PReg::new(2, RegKind::Integer) }
pub const fn w3() -> PReg { PReg::new(3, RegKind::Integer) }
pub const fn w4() -> PReg { PReg::new(4, RegKind::Integer) }
pub const fn w5() -> PReg { PReg::new(5, RegKind::Integer) }
pub const fn w6() -> PReg { PReg::new(6, RegKind::Integer) }
pub const fn w7() -> PReg { PReg::new(7, RegKind::Integer) }
pub const fn w8() -> PReg { PReg::new(8, RegKind::Integer) }
pub const fn w9() -> PReg { PReg::new(9, RegKind::Integer) }
pub const fn w10() -> PReg { PReg::new(10, RegKind::Integer) }
pub const fn w11() -> PReg { PReg::new(11, RegKind::Integer) }
@ -202,31 +159,4 @@ pub const fn w14() -> PReg { PReg::new(14, RegKind::Integer) }
pub const fn w15() -> PReg { PReg::new(15, RegKind::Integer) }
pub const fn w16() -> PReg { PReg::new(16, RegKind::Integer) }
pub const fn w17() -> PReg { PReg::new(17, RegKind::Integer) }
pub const fn w18() -> PReg { PReg::new(18, RegKind::Integer) }
pub const fn w19() -> PReg { PReg::new(19, RegKind::Integer) }
pub const fn w20() -> PReg { PReg::new(20, RegKind::Integer) }
pub const fn w21() -> PReg { PReg::new(21, RegKind::Integer) }
pub const fn w22() -> PReg { PReg::new(22, RegKind::Integer) }
pub const fn w23() -> PReg { PReg::new(23, RegKind::Integer) }
pub const fn w24() -> PReg { PReg::new(24, RegKind::Integer) }
pub const fn w25() -> PReg { PReg::new(25, RegKind::Integer) }
pub const fn w26() -> PReg { PReg::new(26, RegKind::Integer) }
pub const fn w27() -> PReg { PReg::new(27, RegKind::Integer) }
pub const fn w28() -> PReg { PReg::new(28, RegKind::Integer) }
pub const fn w29() -> PReg { PReg::new(29, RegKind::Integer) }
pub const fn w30() -> PReg { PReg::new(30, RegKind::Integer) }
pub const fn w31() -> PReg { PReg::new(31, RegKind::Integer) }
pub const fn wzr() -> PReg { PReg::new(32, RegKind::Integer) }
pub const CALLER_SAVED_REGS: [PReg; 18] = [
w9(), w10(), w11(), w12(), w13(), w14(), w15(), w16(), w17(),
x9(), x10(), x11(), x12(), x13(), x14(), x15(), x16(), x17()
];
pub const CALLEE_SAVED_REGS: [PReg; 20] = [
w19(), w20(), w21(), w22(), w23(), w24(), w25(), w26(), w27(), w28(),
x19(), x20(), x21(), x22(), x23(), x24(), x25(), x26(), x27(), x28(),
];
pub const INT_ARG_REGS: [PReg; 16] = [
w0(), w1(), w2(), w3(), w4(), w5(), w6(), w7(),
x0(), x1(), x2(), x3(), x4(), x5(), x6(), x7()
];
pub const fn wzr() -> PReg { PReg::new(32, RegKind::Integer) }

@ -67,21 +67,9 @@ impl MirGen for ir::function::Function {
mirgen.curr_func = Some(mfunc);
mirgen.funcs.insert(name, mfunc);
mirgen.func_map.insert(mfunc, *self);
// 生成用户函数的基本快
for block in self.iter(mirgen.ctx) {
block.mirgen(mirgen);
}
for (i, &param_val) in self.get_parameters(mirgen.ctx).iter().take(8).enumerate() {
let new_reg = mirgen.mctx.generate_vreg(regs::RegKind::Integer).into();
let preg = mirgen.generate_param_reg(param_val, i as u32);
let mov = MirInst::mov_reg(&mut mirgen.mctx, new_reg, preg);
let _ = mfunc.head(&mirgen.mctx).unwrap().push_back(&mut mirgen.mctx, mov);
let mem_loc = MirOperandKind::Reg(new_reg);
mirgen.table.insert(param_val, MirOperand {
typ: param_val.kind(mirgen.ctx),
kind: mem_loc,
});
}
}
}
@ -112,8 +100,6 @@ impl MirGen for ir::instruction::Instruction {
if let Some(val) = val {
mirgen.gen_ret_move(val);
}
} else {
}
},
_ => todo!(),
@ -123,40 +109,26 @@ impl MirGen for ir::instruction::Instruction {
let result_val = self.get_result(mirgen.ctx).unwrap();
let lhs = self.get_operand(mirgen.ctx, 0).unwrap();
let rhs = self.get_operand(mirgen.ctx, 1).unwrap();
// 创建目标寄存器
let temp_reg = mirgen.mctx.generate_vreg(regs::RegKind::Integer).into();
if !lhs.is_constant(mirgen.ctx) && !rhs.is_constant(mirgen.ctx) {
// 获取左操作数寄存器
let lhs_reg = mirgen.generate_opd_reg(lhs);
// 获取右操作数寄存器
let rhs_reg = mirgen.generate_opd_reg(rhs);
match op {
ir::instruction::BinaryOp::Add => {
// 生成加法指令
let add = MirInst::add(&mut mirgen.mctx, temp_reg, lhs_reg, rhs_reg);
let _ = mirgen.curr_block.as_ref().unwrap().push_back(&mut mirgen.mctx, add);
}
_ => todo!("Unsupported binary operation: {:?}", op),
}
} else if !lhs.is_constant(mirgen.ctx) && rhs.is_constant(mirgen.ctx) {
// 获取左操作数寄存器
let lhs_reg = mirgen.generate_opd_reg(lhs);
// 处理常量右操作数
if let ir::value::ValueKind::Constant { value } = &rhs.deref(mirgen.ctx).unwrap().kind {
if let ConstantValue::Int32 { value, .. } = value {
match op {
ir::instruction::BinaryOp::Add => {
// 生成加法指令
if *value > 4095 || *value < -4096{
// let new_reg = mirgen.mctx.generate_vreg(regs::RegKind::Integer).into();
mirgen.generate_movimm(temp_reg, *value);
let add = MirInst::add(&mut mirgen.mctx, temp_reg, lhs_reg,temp_reg);
let _ = mirgen.curr_block.as_ref().unwrap().push_back(&mut mirgen.mctx, add);
} else{
let addi = MirInst::addi(&mut mirgen.mctx, temp_reg, lhs_reg, *value as i32);
let _ = mirgen.curr_block.as_ref().unwrap().push_back(&mut mirgen.mctx, addi);
}
let addi = MirInst::addi(&mut mirgen.mctx, temp_reg, lhs_reg, *value as i32);
let _ = mirgen.curr_block.as_ref().unwrap().push_back(&mut mirgen.mctx, addi);
},
_ => todo!("Unsupported binary operation: {:?}", op),
}
@ -198,22 +170,13 @@ impl MirGen for ir::instruction::Instruction {
panic!("Expected i32 constant for left operand");
}
} else {
// 获取右操作数寄存器
let rhs_reg = mirgen.generate_opd_reg(rhs);
// 处理常量左操作数
if let ir::value::ValueKind::Constant { value } = &lhs.deref(mirgen.ctx).unwrap().kind {
if let ConstantValue::Int32 { value, .. } = value {
match op {
ir::instruction::BinaryOp::Add => {
// 生成加法指令
if *value > 4095 || *value < -4096 {
mirgen.generate_movimm(temp_reg, *value);
let add = MirInst::add(&mut mirgen.mctx, temp_reg, temp_reg,rhs_reg);
let _ = mirgen.curr_block.as_ref().unwrap().push_back(&mut mirgen.mctx, add);
} else {
let addi = MirInst::addi(&mut mirgen.mctx, temp_reg, rhs_reg, *value);
let _ = mirgen.curr_block.as_ref().unwrap().push_back(&mut mirgen.mctx, addi);
}
let addi = MirInst::addi(&mut mirgen.mctx, temp_reg, rhs_reg, *value);
let _ = mirgen.curr_block.as_ref().unwrap().push_back(&mut mirgen.mctx, addi);
}
_ => todo!("Unsupported binary operation: {:?}", op),
}
@ -233,13 +196,11 @@ impl MirGen for ir::instruction::Instruction {
ir::instruction::InstructionKind::MemAccess { op } => {
match op {
MemAccessOp::Alloca { typ } => {
// 在栈上分配空间
let mut size = typ.bitwidth(mirgen.ctx);
size = (size + 7) / 8;
let current_offset = mirgen.curr_func.unwrap().current_stack_size(&mirgen.mctx);
let _ = mirgen.curr_func.unwrap().add_current_stack_size(&mut mirgen.mctx, size as i32);
let total_stack = mirgen.curr_func.unwrap().calleeargs_stack_size(&mirgen.mctx);
// 非数组值用地址偏移
let total_stack = 0;
let mem_loc = MemLoc::RegOffset { base: regs::sp().into(), offset: total_stack+current_offset };
let mopd = MirOperand {
typ,
@ -250,7 +211,6 @@ impl MirGen for ir::instruction::Instruction {
MemAccessOp::Store => {
let val = self.get_operand(mirgen.ctx, 0).unwrap();
let ptr = self.get_operand(mirgen.ctx, 1).unwrap();
// 检查是否是全局变量
let is_global_ptr =
if let ir::value::ValueKind::Constant { value} = &ptr.deref(mirgen.ctx).unwrap().kind {
matches!(value, ConstantValue::GlobalPtr { .. })
@ -259,7 +219,6 @@ impl MirGen for ir::instruction::Instruction {
false
};
let mem_loc = if is_global_ptr {
// 提取全局变量名称
let name =
if let ir::value::ValueKind::Constant {
value: ConstantValue::GlobalPtr { name, .. }
@ -269,14 +228,10 @@ impl MirGen for ir::instruction::Instruction {
};
let label = mirgen.globals[&name].clone();
let temp_reg = mirgen.mctx.generate_vreg(regs::RegKind::Address).into();
// 生成加载全局地址的指令
mirgen.generate_adrp(temp_reg, label);
// 生成加载实际值的指令
let mem = MemLoc::RegOffset { base: temp_reg, offset: 0 };
mem
}else {
// 处理局部变量存储
let mem = match mirgen.table[&ptr].kind {
MirOperandKind::Mem(m) => m,
_ => unreachable!(),
@ -288,7 +243,6 @@ impl MirGen for ir::instruction::Instruction {
let zero_reg = regs::wzr().into();
match value {
ConstantValue::Int32 { value, .. } => {
// 使用零寄存器或加载立即数
if *value == 0 {
mirgen.generate_str(zero_reg, mem_loc);
} else {
@ -297,12 +251,6 @@ impl MirGen for ir::instruction::Instruction {
mirgen.generate_str(new_reg, mem_loc);
}
}
ConstantValue::Undef{typ:_} => {
}
ConstantValue::Zero { typ:_ }=> {
mirgen.generate_str(zero_reg, mem_loc);
}
_ => todo!(),
}
}
@ -317,14 +265,8 @@ impl MirGen for ir::instruction::Instruction {
}
MirOperandKind::Mem(MemLoc::RegOffset { base, offset }) => {
let new_reg = mirgen.mctx.generate_vreg(regs::RegKind::Address).into();
if offset > 4095 || offset < -4096 {
mirgen.generate_movimm(new_reg, offset);
let add = MirInst::add(&mut mirgen.mctx, new_reg, base, new_reg);
mirgen.curr_block.as_ref().unwrap().push_back(&mut mirgen.mctx, add).unwrap();
} else {
let add = MirInst::addi(&mut mirgen.mctx, new_reg, base, offset);
mirgen.curr_block.as_ref().unwrap().push_back(&mut mirgen.mctx, add).unwrap();
}
let add = MirInst::addi(&mut mirgen.mctx, new_reg, base, offset);
mirgen.curr_block.as_ref().unwrap().push_back(&mut mirgen.mctx, add).unwrap();
let mem_loc = MemLoc::Reg { address: new_reg };
mirgen.generate_str(new_reg, mem_loc);
@ -350,32 +292,6 @@ impl MirGen for ir::instruction::Instruction {
}
}
}
ir::value::ValueKind::Parameter { function:_, index, typ:_ }=>{
if mirgen.table.get(&val).is_some() {
let arg_reg = match mirgen.table[&val].kind {
MirOperandKind::Reg(reg) => reg,
MirOperandKind::Mem(MemLoc::Reg { address }) => address,
_ => todo!(),
};
mirgen.generate_str(arg_reg, mem_loc);
} else {
if *index < 8 {
panic!("Unreachable")
} else {
// 大于八个的参数在栈上通过fp获取
let argadress_reg = mirgen.mctx.generate_vreg(regs::RegKind::Integer).into();
mirgen.generate_ldr(argadress_reg, MemLoc::RegOffset { base: regs::fp().into(), offset: ((*index - 8) * 8) as i32 });
mirgen.generate_str(argadress_reg, mem_loc);
let mem_loc = MirOperandKind::Reg(argadress_reg);
mirgen.table.insert(val, MirOperand {
typ: val.kind(mirgen.ctx),
kind: mem_loc,
});
mirgen.release.insert(val);
}
}
}
_ => todo!()
}
}
@ -391,7 +307,6 @@ impl MirGen for ir::instruction::Instruction {
false
};
let mem_loc = if is_global_ptr {
// 提取全局变量名称
let name =
if let ir::value::ValueKind::Constant {
value: ConstantValue::GlobalPtr { name, .. }
@ -399,14 +314,10 @@ impl MirGen for ir::instruction::Instruction {
else {
unreachable!()
};
// 处理全局变量加载
let label = mirgen.globals[&name].clone();
let temp_reg = mirgen.mctx.generate_vreg(regs::RegKind::Address).into();
// 生成加载全局地址的指令
mirgen.generate_adrp(temp_reg, label);
// 生成加载实际值的指令
let mem = MemLoc::RegOffset { base: temp_reg, offset: 0 };
mem
} else {
@ -416,13 +327,9 @@ impl MirGen for ir::instruction::Instruction {
};
mem
};
// let size = (result_val.kind(mirgen.ctx).bitwidth(mirgen.ctx) + 7) / 8;
let temp_reg = mirgen.mctx.generate_vreg(regs::RegKind::Integer).into()
;
mirgen.generate_ldr(temp_reg, mem_loc);
// 记录结果
let mem_loc = MirOperandKind::Reg(temp_reg);
mirgen.table.insert(result_val, MirOperand {
@ -472,21 +379,18 @@ impl<'s> MirgenContext<'s> {
pub fn mircontext(self) -> MirContext { self.mctx }
pub fn mirgen(&mut self) {
// 处理全局变量
for global_data in self.ctx.globals.iter() {
global_data.mirgen(self);
}
for func in self.ctx.get_functions() {
//println!("Translating function: {}", func.get_id(self.ctx));
func.mirgen(self);
}
// 翻译指令
for func in self.ctx.get_functions() {
self.curr_func = Some(self.funcs[&func.get_id(self.ctx)]);
let mut stack_size = 0;
// 计算函数局部变量栈空间Alloca指令
for block in func.iter(self.ctx) {
self.curr_block = Some(self.blocks[&block]);
for inst in block.iter(self.ctx) {
@ -496,17 +400,12 @@ impl<'s> MirgenContext<'s> {
}
}
stack_size = (stack_size + 7) / 8;
// 调用者保护临时寄存器空间x9-x15
self.curr_func.unwrap().add_storage_stack_size(&mut self.mctx, stack_size as i32);
// 计算函数内部给被调用函数分配的参数空间
let mut callee_stack = 0;
for block in func.iter(self.ctx) {
self.curr_block = Some(self.blocks[&block]);
}
callee_stack = callee_stack*8;
self.curr_func.unwrap().add_calleeargs_stack_size(&mut self.mctx, callee_stack as i32);
let mut blocks = vec![]; //TODO!
let mut blocks = vec![];
for func in self.ctx.get_functions(){
for bbk in func.iter(self.ctx){
blocks.push(bbk.clone());
@ -537,13 +436,12 @@ impl<'s> MirgenContext<'s> {
pub fn gen_ret_move(&mut self, val: Value) {
let curr_block = self.curr_block.unwrap();
let ret_reg = self.generate_ret_reg(val.kind(self.ctx)); // 返回寄存器
let ret_reg = self.generate_ret_reg(val.kind(self.ctx));
match &val.deref(self.ctx).unwrap().kind {
ir::value::ValueKind::Constant { value } => {
match value {
ConstantValue::Int32 { value, .. } => {
// 直接移动到返回寄存器
self.generate_movimm(regs::Reg::P(ret_reg), *value);
}
_ => todo!(),
@ -554,7 +452,6 @@ impl<'s> MirgenContext<'s> {
match mopd.kind {
MirOperandKind::Reg(reg) => {
if reg != regs::Reg::P(ret_reg) {
// 移动值到返回寄存器
let mov = MirInst::mov_reg(&mut self.mctx, regs::Reg::P(ret_reg), reg);
curr_block.push_back(&mut self.mctx, mov).unwrap();
@ -566,36 +463,6 @@ impl<'s> MirgenContext<'s> {
}
}
}
ir::value::ValueKind::Parameter { function:_, index, typ }=>{
if *index < 8 {
let arg_reg = match *index {
0 => regs::w0().into(),
1 => regs::w1().into(),
2 => regs::w2().into(),
3 => regs::w3().into(),
4 => regs::w4().into(),
5 => regs::w5().into(),
6 => regs::w6().into(),
7 => regs::w7().into(),
_ => unreachable!(),
};
if typ.is_int32(self.ctx){
let mov = MirInst::mov_reg(&mut self.mctx, regs::Reg::P(ret_reg), arg_reg);
curr_block.push_back(&mut self.mctx, mov).unwrap();
} else {
panic!("Unsupported Type")
}
} else {
let mem_loc = if *index*8 < 4096 {
MemLoc::RegOffset { base: regs::fp().into(), offset: (*index*8) as i32 }
} else {
let new_reg = self.mctx.generate_vreg(regs::RegKind::Integer).into();
self.generate_movimm(new_reg, (*index*8) as i32);
MemLoc::Reg2Offset { base: regs::fp().into(), offset: new_reg }
};
self.generate_ldr(regs::Reg::P(ret_reg), mem_loc);
}
}
_ => todo!(),
}
}
@ -608,20 +475,6 @@ impl<'s> MirgenContext<'s> {
}
}
pub fn generate_param_reg(&mut self, _arg: ir::value::Value, index: u32) -> Reg {
match index {
0 => regs::w0().into(),
1 => regs::w1().into(),
2 => regs::w2().into(),
3 => regs::w3().into(),
4 => regs::w4().into(),
5 => regs::w5().into(),
6 => regs::w6().into(),
7 => regs::w7().into(),
_ => unreachable!()
}
}
pub fn generate_opd_reg(&mut self, opd: ir::value::Value) -> Reg {
if self.table.get(&opd).is_some() {
let v_opd = self.table[&opd];
@ -631,22 +484,7 @@ impl<'s> MirgenContext<'s> {
}
} else {
match &opd.deref(self.ctx).unwrap().kind {
ir::value::ValueKind::Parameter{ function:_, index, typ:_ } => {
if *index < 8 {
panic!("Unreachable")
} else {
// 大于八个的参数在栈上通过fp获取
let new_reg = self.mctx.generate_vreg(regs::RegKind::Integer).into();
self.generate_ldr(new_reg, MemLoc::RegOffset { base: regs::fp().into(), offset: ((*index - 8) * 8) as i32 });
let mem_loc = MirOperandKind::Reg(new_reg);
self.table.insert(opd, MirOperand {
typ: opd.kind(self.ctx),
kind: mem_loc,
});
new_reg
}
}
_ => panic!("Expected register operand for binary op")
_ => todo!(),
}
}
}
@ -663,43 +501,13 @@ impl<'s> MirgenContext<'s> {
}
pub fn generate_str(&mut self, rm: Reg, mem_loc: MemLoc) {
match mem_loc {
MemLoc::RegOffset { base, offset } => {
if offset > 255 || offset < -256{
let temp_reg = self.mctx.generate_vreg(regs::RegKind::Integer).into();
self.generate_movimm(temp_reg, offset);
let str = MirInst::str(&mut self.mctx, rm, MemLoc::Reg2Offset { base: base, offset: temp_reg });
let _ = self.curr_block.as_ref().unwrap().push_back(&mut self.mctx, str);
} else {
let str = MirInst::str(&mut self.mctx, rm, mem_loc);
let _ = self.curr_block.as_ref().unwrap().push_back(&mut self.mctx, str);
}
},
_ => {
let str = MirInst::str(&mut self.mctx, rm, mem_loc);
let _ = self.curr_block.as_ref().unwrap().push_back(&mut self.mctx, str);
}
}
let str = MirInst::str(&mut self.mctx, rm, mem_loc);
let _ = self.curr_block.as_ref().unwrap().push_back(&mut self.mctx, str);
}
pub fn generate_ldr(&mut self, rd: Reg, mem_loc: MemLoc) {
match mem_loc {
MemLoc::RegOffset { base, offset } => {
if offset > 255 || offset < -256{
let temp_reg = self.mctx.generate_vreg(regs::RegKind::Integer).into();
self.generate_movimm(temp_reg, offset);
let ldr = MirInst::ldr(&mut self.mctx, rd, MemLoc::Reg2Offset { base: base, offset: temp_reg});
let _ = self.curr_block.as_ref().unwrap().push_back(&mut self.mctx, ldr);
} else {
let ldr = MirInst::ldr(&mut self.mctx, rd, mem_loc);
let _ = self.curr_block.as_ref().unwrap().push_back(&mut self.mctx, ldr);
}
}
_ => {
let ldr = MirInst::ldr(&mut self.mctx, rd, mem_loc);
let _ = self.curr_block.as_ref().unwrap().push_back(&mut self.mctx, ldr);
}
}
let ldr = MirInst::ldr(&mut self.mctx, rd, mem_loc);
let _ = self.curr_block.as_ref().unwrap().push_back(&mut self.mctx, ldr);
}
pub fn generate_adrp(&mut self, rd: Reg, label: MirLabel ) {
@ -710,13 +518,3 @@ impl<'s> MirgenContext<'s> {
}
}
pub fn find_additive_decomposition(n: i32) -> Option<(u32, u32)> {
if n.count_ones() == 2 {
let a = 31 - n.leading_zeros();
let b = n.trailing_zeros();
//println!("n: {} -> {}, {}", n, a, b);
Some((a, b))
} else {
None
}
}

@ -21,52 +21,34 @@ pub fn allocate_reg(_mctx: &mut MirContext, _vreg: regs::VReg, candidates: &[reg
}
pub fn regalloc(mctx: &mut MirContext) {
// 硬件寄存器状态(9-15和19-28可以用来分配)
let hw_reg_used: [bool; 29] = array::from_fn(|i| {
!((9..=14).contains(&i) || (19..=28).contains(&i))
});
let hw_reg_used: [bool; 29] = array::from_fn(|i| {!(9..=17).contains(&i)});
let integer_candidates = vec![
regs::w19(), regs::w20(), regs::w21(), regs::w22(), regs::w23(), regs::w24(), regs::w25(), regs::w26(), regs::w27(), regs::w28(),
regs::w9(), regs::w10(), regs::w11(), regs::w12(), regs::w13(), regs::w14(), regs::w15(), regs::w16(), regs::w17(),
];
let address_candidates = vec![
regs::x19(), regs::x20(), regs::x21(), regs::x22(), regs::x23(), regs::x24(), regs::x25(), regs::x26(), regs::x27(), regs::x28(),
regs::x9(), regs::x10(), regs::x11(), regs::x12(), regs::x13(), regs::x14(), regs::x15(), regs::x16(), regs::x17(),
];
// 预先收集所有函数的信息
let mut func_info = Vec::new();
for func_data in mctx.funcs.iter() {
let function = func_data.self_ptr();
if function.is_external(mctx) {
continue;
}
let mut all_vregs = HashSet::new();
// 使用不可变借用收集虚拟寄存器
{
for block in function.iter(&mctx) {
for inst in block.iter(&mctx) {
let mut collect_reg = |reg: Reg| {
if let Reg::V(vreg) = reg {
all_vregs.insert(vreg);
}
};
let cur_regs = inst.all_regs(&mctx);
for reg in cur_regs {
collect_reg(reg);
for block in function.iter(&mctx) {
for inst in block.iter(&mctx) {
for reg in inst.all_regs(&mctx) {
if let Reg::V(vreg) = reg {
all_vregs.insert(vreg);
}
}
}
}
func_info.push((function, all_vregs));
}
// 现在使用可变借用来处理每个函数
for (function, all_vregs) in func_info {
let curr_func = Some(function);
let mut reg_map = HashMap::new();
let mut spill_map = HashMap::new();
let mut available_regs = hw_reg_used.clone();
let mut spilled_registers = HashSet::new();
let mut use_count = HashMap::new();
for block in function.iter(mctx) {
@ -78,108 +60,23 @@ pub fn regalloc(mctx: &mut MirContext) {
}
}
}
let mut sorted_vregs: Vec<_> = all_vregs.iter().collect();
// 使用频率降序排除
sorted_vregs.sort_by(|a,b| use_count.get(b).cmp(&use_count.get(a)));
let vregs: Vec<_> = all_vregs.iter().collect();
// 分配物理寄存器
for &vreg in &sorted_vregs {
for &vreg in &vregs {
let preg = match vreg.kind() {
regs::RegKind::Integer => allocate_reg(mctx, *vreg, &integer_candidates, &mut available_regs),
regs::RegKind::Address => allocate_reg(mctx, *vreg, &address_candidates, &mut available_regs),
};
if let Some(preg) = preg {
reg_map.insert(vreg, preg);
} else {
spilled_registers.insert(vreg);
}
}
for &reg in &spilled_registers {
let e = match reg.kind() {
regs::RegKind::Integer => 4,
_ => 8
};
let cur_stack = curr_func.unwrap().storage_stack_size(mctx) + curr_func.unwrap().calleeargs_stack_size(mctx);
spill_map.insert(reg, cur_stack);
curr_func.unwrap().add_storage_stack_size(mctx, e);
}
// 处理每条指令的溢出
curr_func.unwrap().add_storage_stack_size(mctx, 19*8+24*4);
let mut curr_block = function.head(mctx);
while let Some(block) = curr_block {
let mut curr_inst = block.head(mctx);
while let Some(inst) = curr_inst {
let next_inst = inst.succ(mctx);
// 处理源操作数(uses)
let mut spill_reg_index = 0;
for reg in inst.uses(mctx) {
if let Reg::V(vreg) = reg {
if let Some(spill_slot) = spill_map.get(&vreg) {
let spill_reg = if spill_reg_index == 0 {
match vreg.kind() {
regs::RegKind::Address => regs::x15().into(),
regs::RegKind::Integer => regs::w15().into(),
}
} else if spill_reg_index == 1{
match vreg.kind() {
regs::RegKind::Address => regs::x16().into(),
regs::RegKind::Integer => regs::w16().into(),
_ => todo!(),
}
} else {
match vreg.kind() {
regs::RegKind::Address => regs::x17().into(),
regs::RegKind::Integer => regs::w17().into(),
_ => todo!(),
}
};
spill_reg_index += 1;
let spill_offset = *spill_slot;
generate_spill_load(
mctx,
spill_reg,
MemLoc::RegOffset { base: regs::sp().into(), offset: spill_offset },
inst
);
// 即使目的操作数也是源操作数
let flag = if inst.def(mctx).contains(&reg) {
true
} else {
false
};
inst.replace_regs(mctx, Reg::V(vreg), spill_reg);
if flag {
generate_spill_store(
mctx,
spill_reg,
MemLoc::RegOffset { base: regs::sp().into(), offset: spill_offset },
inst
);
}
}
}
}
// 处理目标操作数(defs)
for reg in inst.def(mctx) {
if let Reg::V(vreg) = reg {
if let Some(spill_slot) = spill_map.get(&vreg) {
let spill_reg = match vreg.kind() {
regs::RegKind::Address => regs::x15().into(),
regs::RegKind::Integer => regs::w15().into(),
};
let spill_offset = *spill_slot;
inst.replace_regs(mctx, Reg::V(vreg), spill_reg);
generate_spill_store(
mctx,
spill_reg,
MemLoc::RegOffset { base: regs::sp().into(), offset: spill_offset },
inst
);
}
}
}
// 替换非溢出的虚拟寄存器和调整偏移
for reg in inst.all_regs(mctx) {
if let Reg::V(vreg) = reg {
if let Some(allocated_reg) = reg_map.get(&vreg) {
@ -194,32 +91,18 @@ pub fn regalloc(mctx: &mut MirContext) {
generate_prologue(mctx,curr_func.unwrap());
generate_epilogue(mctx, curr_func.unwrap());
}
}
pub fn generate_spill_load(mctx: &mut MirContext, reg: Reg, mem_loc: MemLoc, inst: MirInst) {
let load = MirInst::ldr(mctx, reg.into(), mem_loc);
let _ = inst.insert_before(mctx, load);
}
pub fn generate_spill_store(mctx: &mut MirContext, reg: Reg, mem_loc: MemLoc, inst: MirInst) {
let store = MirInst::str(mctx, reg.into(), mem_loc);
let _ = inst.insert_after(mctx, store);
}
}
pub fn generate_prologue(mctx: &mut MirContext, function: MirFunction) {
function.add_callee_reg(mctx, regs::fp().into());
function.add_callee_reg(mctx, regs::x30().into());
let mut stack_size = function.storage_stack_size(mctx) + function.calleeargs_stack_size(mctx) + function.callee_regs(mctx).len() as i32 * 8;
let mut stack_size = function.storage_stack_size(mctx);
stack_size = (stack_size + 15) & !15;
let sub = MirInst::subi(mctx, regs::sp().into(), regs::sp().into(), stack_size);
function.head(mctx).unwrap().push_front(mctx, sub).unwrap();
}
pub fn generate_epilogue(mctx: &mut MirContext, function: MirFunction) {
let mut stack_size = function.storage_stack_size(mctx) + function.calleeargs_stack_size(mctx) + function.callee_regs(mctx).len() as i32 * 8;
let mut stack_size = function.storage_stack_size(mctx);
stack_size = (stack_size + 15) & !15;
// let ldp = MirInst::ldp(mctx, regs::fp().into(), regs::x30().into(), MemLoc::RegOffset{base: regs::sp().into(), offset: (stack_size - 16) });
let addi = MirInst::addi(mctx, regs::sp().into(), regs::sp().into(), stack_size );
let ret = MirInst::ret(mctx);
function.tail(mctx).unwrap().push_back(mctx, addi).unwrap();

Loading…
Cancel
Save