|
|
|
|
@ -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, ¶m_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
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|