From 0fea4027ad275c454564668de7a6021c1131f0f8 Mon Sep 17 00:00:00 2001 From: static Date: Wed, 18 Jun 2025 03:06:34 +0000 Subject: [PATCH] HW8 (8) --- src/asmgen/mod.rs | 129 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 89 insertions(+), 40 deletions(-) diff --git a/src/asmgen/mod.rs b/src/asmgen/mod.rs index de4b626..2700cf1 100644 --- a/src/asmgen/mod.rs +++ b/src/asmgen/mod.rs @@ -249,7 +249,7 @@ impl InferenceGraph { if !analysis.has_memcpy_in_prologue { for (aid, dtype) in code.blocks[&code.bid_init].phinodes.iter().enumerate() { let rid = ir::RegisterId::arg(code.bid_init, aid); - if analysis.is_temporary2(&rid, &lives) { + if analysis.is_temporary2(&rid, &lives, true) { if is_integer(dtype) { let (_, asm_reg) = vertices.get_mut(&rid).unwrap(); *asm_reg = asm::Register::arg( @@ -269,7 +269,7 @@ impl InferenceGraph { for (bid, iid, _, reg) in &analysis.calls { let rid = ir::RegisterId::temp(*bid, *iid); - if analysis.is_temporary2(&rid, &lives) { + if analysis.is_temporary2(&rid, &lives, true) { if let Some(reg) = reg { let (_, asm_reg) = vertices.get_mut(&rid).unwrap(); *asm_reg = *reg; @@ -307,6 +307,7 @@ impl InferenceGraph { reg, asm::Register::Saved(asm::RegisterType::Integer, _) | asm::Register::Arg(asm::RegisterType::Integer, _) + | asm::Register::Temp(asm::RegisterType::Integer, _) ) { return Some(*reg); @@ -316,6 +317,7 @@ impl InferenceGraph { reg, asm::Register::Saved(asm::RegisterType::FloatingPoint, _) | asm::Register::Arg(asm::RegisterType::FloatingPoint, _) + | asm::Register::Temp(asm::RegisterType::FloatingPoint, _) ) { return Some(*reg); @@ -324,6 +326,19 @@ impl InferenceGraph { }) .collect::>(); if is_integer(dtype) { + let smallest_temp_reg = smallest_missing_integer( + &neighbor_registers + .iter() + .filter_map(|reg| { + if let asm::Register::Temp(_, i) = reg { + Some(*i) + } else { + None + } + }) + .collect(), + 3, + ); // t0~2는 못 씀 let smallest_arg_reg = smallest_missing_integer( &neighbor_registers .iter() @@ -350,7 +365,15 @@ impl InferenceGraph { .collect(), 1, ); // s0는 못 씀 - if smallest_arg_reg <= 7 && analysis.is_temporary2(&rid, &lives) { + if smallest_temp_reg <= 6 && analysis.is_temporary2(&rid, &lives, false) { + let _unused = vertices.insert( + rid, + ( + dtype.clone(), + asm::Register::temp(asm::RegisterType::Integer, smallest_temp_reg), + ), + ); + } else if smallest_arg_reg <= 7 && analysis.is_temporary2(&rid, &lives, true) { let _unused = vertices.insert( rid, ( @@ -370,6 +393,19 @@ impl InferenceGraph { // Spilling } } else if is_float(dtype) { + let smallest_temp_reg = smallest_missing_integer( + &neighbor_registers + .iter() + .filter_map(|reg| { + if let asm::Register::Temp(_, i) = reg { + Some(*i) + } else { + None + } + }) + .collect(), + 2, + ); // ft0~1은 못 씀 let smallest_arg_reg = smallest_missing_integer( &neighbor_registers .iter() @@ -396,7 +432,18 @@ impl InferenceGraph { .collect(), 0, ); - if smallest_arg_reg <= 7 && analysis.is_temporary2(&rid, &lives) { + if smallest_temp_reg <= 11 && analysis.is_temporary2(&rid, &lives, false) { + let _unused = vertices.insert( + rid, + ( + dtype.clone(), + asm::Register::temp( + asm::RegisterType::FloatingPoint, + smallest_temp_reg, + ), + ), + ); + } else if smallest_arg_reg <= 7 && analysis.is_temporary2(&rid, &lives, true) { let _unused = vertices.insert( rid, ( @@ -493,6 +540,7 @@ impl Analysis { &self, reg: &ir::RegisterId, lives: &HashMap>, + is_a_reg: bool, ) -> bool { for (call_bid, call_iid, call_args, _) in &self.calls { let lives_before = lives @@ -501,7 +549,8 @@ impl Analysis { let lives_after = lives .get(&ir::RegisterId::temp(*call_bid, call_iid + 1)) .unwrap(); - if lives_before.contains(reg) && (call_args.contains(reg) || lives_after.contains(reg)) + if lives_before.contains(reg) + && ((is_a_reg && call_args.contains(reg)) || lives_after.contains(reg)) { return false; } @@ -920,14 +969,14 @@ impl Asmgen { packing_size += field_size; } else { self.translate_addi( - asm::Register::T5, + asm::Register::T2, asm::Register::S0, stack_offset, &mut insts, ); insts.push(asm::Instruction::SType { instr: asm::SType::SD, - rs1: asm::Register::T5, + rs1: asm::Register::T2, rs2: asm::Register::arg( asm::RegisterType::Integer, num_int_args, @@ -941,14 +990,14 @@ impl Asmgen { } else if is_float(field_dtype) { if is_packing { self.translate_addi( - asm::Register::T5, + asm::Register::T2, asm::Register::S0, stack_offset, &mut insts, ); insts.push(asm::Instruction::SType { instr: asm::SType::SD, - rs1: asm::Register::T5, + rs1: asm::Register::T2, rs2: asm::Register::arg( asm::RegisterType::Integer, num_int_args, @@ -960,14 +1009,14 @@ impl Asmgen { } self.translate_addi( - asm::Register::T5, + asm::Register::T2, asm::Register::S0, stack_offset, &mut insts, ); insts.push(asm::Instruction::SType { instr: asm::SType::store(field_dtype.deref().clone()), - rs1: asm::Register::T5, + rs1: asm::Register::T2, rs2: asm::Register::arg( asm::RegisterType::FloatingPoint, num_float_args, @@ -982,14 +1031,14 @@ impl Asmgen { if is_packing { self.translate_addi( - asm::Register::T5, + asm::Register::T2, asm::Register::S0, stack_offset, &mut insts, ); insts.push(asm::Instruction::SType { instr: asm::SType::SD, - rs1: asm::Register::T5, + rs1: asm::Register::T2, rs2: asm::Register::arg(asm::RegisterType::Integer, num_int_args), imm: asm::Immediate::Value(packing_start_offset as u64), }); @@ -1908,7 +1957,7 @@ impl Asmgen { ir::Operand::Register { rid, .. } => match rid { ir::RegisterId::Temp { bid, iid } => { self.translate_addi( - asm::Register::T5, + asm::Register::T2, asm::Register::S0, context.stack_offsets[rid], &mut context.insts, @@ -1952,7 +2001,7 @@ impl Asmgen { asm::RegisterType::Integer, num_int_args, ), - rs1: asm::Register::T5, + rs1: asm::Register::T2, imm: asm::Immediate::Value( packing_start_offset as u64, ), @@ -1970,7 +2019,7 @@ impl Asmgen { asm::RegisterType::Integer, num_int_args, ), - rs1: asm::Register::T5, + rs1: asm::Register::T2, imm: asm::Immediate::Value( packing_start_offset as u64, ), @@ -1985,7 +2034,7 @@ impl Asmgen { asm::RegisterType::FloatingPoint, num_float_args, ), - rs1: asm::Register::T5, + rs1: asm::Register::T2, imm: asm::Immediate::Value(packing_start_offset as u64), }); num_float_args += 1; @@ -2001,7 +2050,7 @@ impl Asmgen { asm::RegisterType::Integer, num_int_args, ), - rs1: asm::Register::T5, + rs1: asm::Register::T2, imm: asm::Immediate::Value(packing_start_offset as u64), }); num_int_args += 1; @@ -2115,14 +2164,14 @@ impl Asmgen { .unwrap(); if is_integer(field_dtype) { self.translate_addi( - asm::Register::T5, + asm::Register::T2, asm::Register::S0, context.stack_offsets[&rid], &mut context.insts, ); context.insts.push(asm::Instruction::SType { instr: asm::SType::store(field_dtype.deref().clone()), - rs1: asm::Register::T5, + rs1: asm::Register::T2, rs2: asm::Register::arg( asm::RegisterType::Integer, num_int_fields, @@ -2132,14 +2181,14 @@ impl Asmgen { num_int_fields += 1; } else if is_float(field_dtype) { self.translate_addi( - asm::Register::T5, + asm::Register::T2, asm::Register::S0, context.stack_offsets[&rid], &mut context.insts, ); context.insts.push(asm::Instruction::SType { instr: asm::SType::store(field_dtype.deref().clone()), - rs1: asm::Register::T5, + rs1: asm::Register::T2, rs2: asm::Register::arg( asm::RegisterType::FloatingPoint, num_float_fields, @@ -2623,7 +2672,7 @@ impl Asmgen { }, ir::Operand::Register { rid, .. } => match rid { ir::RegisterId::Temp { bid, iid } => self.translate_addi( - asm::Register::T5, + asm::Register::T2, asm::Register::S0, context.stack_offsets[rid], &mut context.insts, @@ -2648,7 +2697,7 @@ impl Asmgen { asm::RegisterType::Integer, num_int_fields, ), - rs1: asm::Register::T5, + rs1: asm::Register::T2, imm: asm::Immediate::Value(offset as u64), }); num_int_fields += 1; @@ -2659,7 +2708,7 @@ impl Asmgen { asm::RegisterType::FloatingPoint, num_float_fields, ), - rs1: asm::Register::T5, + rs1: asm::Register::T2, imm: asm::Immediate::Value(offset as u64), }); num_float_fields += 1; @@ -2717,13 +2766,13 @@ impl Asmgen { 32 => context .insts .push(asm::Instruction::Pseudo(asm::Pseudo::Li { - rd: asm::Register::T4, + rd: asm::Register::T2, imm: (*value as f32).to_bits() as u64, })), 64 => context .insts .push(asm::Instruction::Pseudo(asm::Pseudo::Li { - rd: asm::Register::T4, + rd: asm::Register::T2, imm: value.to_bits(), })), _ => unreachable!(), @@ -2731,7 +2780,7 @@ impl Asmgen { context.insts.push(asm::Instruction::RType { instr: asm::RType::fmv_int_to_float(ir::Dtype::float(width)), rd, - rs1: asm::Register::T4, + rs1: asm::Register::T2, rs2: None, }); } @@ -3101,14 +3150,14 @@ impl Asmgen { }); } else { insts.push(asm::Instruction::Pseudo(asm::Pseudo::Li { - rd: asm::Register::T3, + rd: asm::Register::T2, imm, })); insts.push(asm::Instruction::RType { instr: asm::RType::add(ir::Dtype::int(64)), rd, rs1, - rs2: Some(asm::Register::T3), + rs2: Some(asm::Register::T2), }); } } @@ -3131,18 +3180,18 @@ impl Asmgen { }); } else { insts.push(asm::Instruction::Pseudo(asm::Pseudo::Li { - rd: asm::Register::T3, + rd: asm::Register::T2, imm, })); insts.push(asm::Instruction::RType { instr: asm::RType::add(ir::Dtype::int(64)), - rd: asm::Register::T3, + rd: asm::Register::T2, rs1, - rs2: Some(asm::Register::T3), + rs2: Some(asm::Register::T2), }); insts.push(asm::Instruction::SType { instr, - rs1: asm::Register::T3, + rs1: asm::Register::T2, rs2, imm: asm::Immediate::Value(0), }); @@ -3167,19 +3216,19 @@ impl Asmgen { }); } else { insts.push(asm::Instruction::Pseudo(asm::Pseudo::Li { - rd: asm::Register::T3, + rd: asm::Register::T2, imm, })); insts.push(asm::Instruction::RType { instr: asm::RType::add(ir::Dtype::int(64)), - rd: asm::Register::T3, + rd: asm::Register::T2, rs1, - rs2: Some(asm::Register::T3), + rs2: Some(asm::Register::T2), }); insts.push(asm::Instruction::IType { instr, rd, - rs1: asm::Register::T3, + rs1: asm::Register::T2, imm: asm::Immediate::Value(0), }); } @@ -3204,8 +3253,8 @@ fn get_rhs_register(dtype: &ir::Dtype) -> asm::Register { fn get_res_register(dtype: &ir::Dtype) -> asm::Register { match dtype { - ir::Dtype::Int { .. } | ir::Dtype::Pointer { .. } => asm::Register::T2, - ir::Dtype::Float { .. } => asm::Register::FT2, + ir::Dtype::Int { .. } | ir::Dtype::Pointer { .. } => asm::Register::T1, + ir::Dtype::Float { .. } => asm::Register::FT1, _ => todo!(), } }