mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-16 23:48:48 +00:00
HW8 (1)
This commit is contained in:
@@ -61,6 +61,25 @@ impl Asmgen {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.variables.push(asm::Section::new(
|
||||||
|
vec![
|
||||||
|
asm::Directive::Globl(asm::Label(name.clone())),
|
||||||
|
asm::Directive::Section(asm::SectionType::Data),
|
||||||
|
asm::Directive::Type(asm::Label(name.clone()), asm::SymbolType::Object),
|
||||||
|
],
|
||||||
|
asm::Variable::new(asm::Label(name.clone()), directives),
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
let mut directives = Vec::new();
|
||||||
|
|
||||||
|
match dtype {
|
||||||
|
ir::Dtype::Array { inner, size } => directives.push(asm::Directive::Zero(
|
||||||
|
size * (get_dtype_size(inner, structs) as usize),
|
||||||
|
)),
|
||||||
|
_ => directives
|
||||||
|
.push(asm::Directive::Zero(get_dtype_size(dtype, structs) as usize)),
|
||||||
|
}
|
||||||
|
|
||||||
self.variables.push(asm::Section::new(
|
self.variables.push(asm::Section::new(
|
||||||
vec![
|
vec![
|
||||||
asm::Directive::Globl(asm::Label(name.clone())),
|
asm::Directive::Globl(asm::Label(name.clone())),
|
||||||
@@ -188,15 +207,19 @@ impl Asmgen {
|
|||||||
let mut num_int_args = 0;
|
let mut num_int_args = 0;
|
||||||
let mut num_float_args = 0;
|
let mut num_float_args = 0;
|
||||||
|
|
||||||
if is_struct(&signature.ret, structs).is_some() {
|
if let Some(size) = is_struct(&signature.ret, structs) {
|
||||||
num_int_args += 1;
|
if size > 16 {
|
||||||
|
num_int_args += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut large_struct = HashMap::new();
|
||||||
|
|
||||||
for (i, dtype) in signature.params.iter().enumerate() {
|
for (i, dtype) in signature.params.iter().enumerate() {
|
||||||
let stack_offset = stack_offsets[&ir::RegisterId::arg(definition.bid_init, i)];
|
let stack_offset = stack_offsets[&ir::RegisterId::arg(definition.bid_init, i)];
|
||||||
if is_integer(dtype) {
|
if is_integer(dtype) {
|
||||||
self.translate_store(
|
self.translate_store(
|
||||||
asm::SType::SD,
|
asm::SType::store(dtype.clone()),
|
||||||
asm::Register::S0,
|
asm::Register::S0,
|
||||||
asm::Register::arg(asm::RegisterType::Integer, num_int_args),
|
asm::Register::arg(asm::RegisterType::Integer, num_int_args),
|
||||||
stack_offset,
|
stack_offset,
|
||||||
@@ -212,6 +235,113 @@ impl Asmgen {
|
|||||||
&mut insts,
|
&mut insts,
|
||||||
);
|
);
|
||||||
num_float_args += 1;
|
num_float_args += 1;
|
||||||
|
} else if let Some(size) = is_struct(dtype, structs) {
|
||||||
|
if size > 16 {
|
||||||
|
let _ = large_struct.insert(i, num_int_args);
|
||||||
|
num_int_args += 1;
|
||||||
|
} else {
|
||||||
|
let struct_name = dtype.get_struct_name().unwrap().as_ref().unwrap().clone();
|
||||||
|
let struct_dtype = structs[&struct_name].clone().unwrap();
|
||||||
|
let fields = struct_dtype.get_struct_fields().unwrap().as_ref().unwrap();
|
||||||
|
|
||||||
|
let mut is_packing = false;
|
||||||
|
let mut packing_start_offset = 0;
|
||||||
|
let mut packing_size = 0;
|
||||||
|
|
||||||
|
for field_dtype in fields {
|
||||||
|
let (offset, _) = struct_dtype
|
||||||
|
.get_offset_struct_field(field_dtype.name().unwrap(), structs)
|
||||||
|
.unwrap();
|
||||||
|
let field_size = get_dtype_size(&field_dtype, structs);
|
||||||
|
if is_integer(&field_dtype) {
|
||||||
|
if !is_packing {
|
||||||
|
is_packing = true;
|
||||||
|
packing_start_offset = offset;
|
||||||
|
packing_size = field_size;
|
||||||
|
} else {
|
||||||
|
if offset == packing_start_offset + (packing_size as usize)
|
||||||
|
&& packing_size + field_size <= 8
|
||||||
|
{
|
||||||
|
packing_size += field_size;
|
||||||
|
} else {
|
||||||
|
self.translate_addi(
|
||||||
|
asm::Register::T5,
|
||||||
|
asm::Register::S0,
|
||||||
|
stack_offset,
|
||||||
|
&mut insts,
|
||||||
|
);
|
||||||
|
insts.push(asm::Instruction::SType {
|
||||||
|
instr: asm::SType::SD,
|
||||||
|
rs1: asm::Register::T5,
|
||||||
|
rs2: asm::Register::arg(
|
||||||
|
asm::RegisterType::Integer,
|
||||||
|
num_int_args,
|
||||||
|
),
|
||||||
|
imm: asm::Immediate::Value(packing_start_offset as u64),
|
||||||
|
});
|
||||||
|
num_int_args += 1;
|
||||||
|
packing_start_offset = offset;
|
||||||
|
packing_size = field_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if is_float(&field_dtype) {
|
||||||
|
if is_packing {
|
||||||
|
self.translate_addi(
|
||||||
|
asm::Register::T5,
|
||||||
|
asm::Register::S0,
|
||||||
|
stack_offset,
|
||||||
|
&mut insts,
|
||||||
|
);
|
||||||
|
insts.push(asm::Instruction::SType {
|
||||||
|
instr: asm::SType::SD,
|
||||||
|
rs1: asm::Register::T5,
|
||||||
|
rs2: asm::Register::arg(
|
||||||
|
asm::RegisterType::Integer,
|
||||||
|
num_int_args,
|
||||||
|
),
|
||||||
|
imm: asm::Immediate::Value(packing_start_offset as u64),
|
||||||
|
});
|
||||||
|
num_int_args += 1;
|
||||||
|
is_packing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.translate_addi(
|
||||||
|
asm::Register::T5,
|
||||||
|
asm::Register::S0,
|
||||||
|
stack_offset,
|
||||||
|
&mut insts,
|
||||||
|
);
|
||||||
|
insts.push(asm::Instruction::SType {
|
||||||
|
instr: asm::SType::store(field_dtype.deref().clone()),
|
||||||
|
rs1: asm::Register::T5,
|
||||||
|
rs2: asm::Register::arg(
|
||||||
|
asm::RegisterType::FloatingPoint,
|
||||||
|
num_float_args,
|
||||||
|
),
|
||||||
|
imm: asm::Immediate::Value(offset as u64),
|
||||||
|
});
|
||||||
|
num_float_args += 1;
|
||||||
|
} else {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_packing {
|
||||||
|
self.translate_addi(
|
||||||
|
asm::Register::T5,
|
||||||
|
asm::Register::S0,
|
||||||
|
stack_offset,
|
||||||
|
&mut insts,
|
||||||
|
);
|
||||||
|
insts.push(asm::Instruction::SType {
|
||||||
|
instr: asm::SType::SD,
|
||||||
|
rs1: asm::Register::T5,
|
||||||
|
rs2: asm::Register::arg(asm::RegisterType::Integer, num_int_args),
|
||||||
|
imm: asm::Immediate::Value(packing_start_offset as u64),
|
||||||
|
});
|
||||||
|
num_int_args += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,46 +367,49 @@ impl Asmgen {
|
|||||||
for (i, dtype) in signature.params.iter().enumerate() {
|
for (i, dtype) in signature.params.iter().enumerate() {
|
||||||
let stack_offset = stack_offsets[&ir::RegisterId::arg(definition.bid_init, i)];
|
let stack_offset = stack_offsets[&ir::RegisterId::arg(definition.bid_init, i)];
|
||||||
if let Some(size) = is_struct(dtype, structs) {
|
if let Some(size) = is_struct(dtype, structs) {
|
||||||
self.translate_addi(
|
if size > 16 {
|
||||||
asm::Register::A0,
|
let reg_index = large_struct[&i];
|
||||||
asm::Register::S0,
|
|
||||||
stack_offset,
|
|
||||||
&mut insts,
|
|
||||||
);
|
|
||||||
|
|
||||||
match i {
|
self.translate_addi(
|
||||||
0 => insts.push(asm::Instruction::IType {
|
asm::Register::A0,
|
||||||
instr: asm::IType::LD,
|
asm::Register::S0,
|
||||||
rd: asm::Register::A1,
|
stack_offset,
|
||||||
rs1: asm::Register::S0,
|
&mut insts,
|
||||||
imm: asm::Immediate::Value(!24 + 1),
|
);
|
||||||
}),
|
|
||||||
1 => insts.push(asm::Instruction::IType {
|
match reg_index {
|
||||||
instr: asm::IType::LD,
|
0 => insts.push(asm::Instruction::IType {
|
||||||
rd: asm::Register::A1,
|
instr: asm::IType::LD,
|
||||||
rs1: asm::Register::Sp,
|
rd: asm::Register::A1,
|
||||||
imm: asm::Immediate::Value(0),
|
rs1: asm::Register::S0,
|
||||||
}),
|
imm: asm::Immediate::Value(!24 + 1),
|
||||||
2 => insts.push(asm::Instruction::IType {
|
}),
|
||||||
instr: asm::IType::LD,
|
1 => insts.push(asm::Instruction::IType {
|
||||||
rd: asm::Register::A1,
|
instr: asm::IType::LD,
|
||||||
rs1: asm::Register::Sp,
|
rd: asm::Register::A1,
|
||||||
imm: asm::Immediate::Value(8),
|
rs1: asm::Register::Sp,
|
||||||
}),
|
imm: asm::Immediate::Value(0),
|
||||||
_ => insts.push(asm::Instruction::Pseudo(asm::Pseudo::Mv {
|
}),
|
||||||
rd: asm::Register::A1,
|
2 => insts.push(asm::Instruction::IType {
|
||||||
rs: asm::Register::arg(asm::RegisterType::Integer, i),
|
instr: asm::IType::LD,
|
||||||
})),
|
rd: asm::Register::A1,
|
||||||
|
rs1: asm::Register::Sp,
|
||||||
|
imm: asm::Immediate::Value(8),
|
||||||
|
}),
|
||||||
|
_ => insts.push(asm::Instruction::Pseudo(asm::Pseudo::Mv {
|
||||||
|
rd: asm::Register::A1,
|
||||||
|
rs: asm::Register::arg(asm::RegisterType::Integer, reg_index),
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
|
||||||
|
insts.push(asm::Instruction::Pseudo(asm::Pseudo::Li {
|
||||||
|
rd: asm::Register::A2,
|
||||||
|
imm: size,
|
||||||
|
}));
|
||||||
|
insts.push(asm::Instruction::Pseudo(asm::Pseudo::Call {
|
||||||
|
offset: asm::Label(String::from("memcpy")),
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
insts.push(asm::Instruction::Pseudo(asm::Pseudo::Li {
|
|
||||||
rd: asm::Register::A2,
|
|
||||||
imm: size,
|
|
||||||
}));
|
|
||||||
insts.push(asm::Instruction::Pseudo(asm::Pseudo::Call {
|
|
||||||
offset: asm::Label(String::from("memcpy")),
|
|
||||||
}));
|
|
||||||
num_int_args += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,6 +574,9 @@ impl Asmgen {
|
|||||||
rs1,
|
rs1,
|
||||||
rs2: Some(rs2),
|
rs2: Some(rs2),
|
||||||
});
|
});
|
||||||
|
context
|
||||||
|
.insts
|
||||||
|
.push(asm::Instruction::Pseudo(asm::Pseudo::Snez { rd, rs: rd }));
|
||||||
}
|
}
|
||||||
ast::BinaryOperator::Less => {
|
ast::BinaryOperator::Less => {
|
||||||
if is_integer(&operand_dtype) {
|
if is_integer(&operand_dtype) {
|
||||||
@@ -716,7 +852,7 @@ impl Asmgen {
|
|||||||
let value_dtype = ptr_dtype.get_pointer_inner().unwrap().clone();
|
let value_dtype = ptr_dtype.get_pointer_inner().unwrap().clone();
|
||||||
if let Some(size) = is_struct(&value_dtype, structs) {
|
if let Some(size) = is_struct(&value_dtype, structs) {
|
||||||
match ptr_rid {
|
match ptr_rid {
|
||||||
ir::RegisterId::Temp { .. } => {
|
ir::RegisterId::Temp { .. } | ir::RegisterId::Arg { .. } => {
|
||||||
let rs1 = get_rhs_register(ptr_dtype);
|
let rs1 = get_rhs_register(ptr_dtype);
|
||||||
self.translate_load_operand(ptr, rs1, context);
|
self.translate_load_operand(ptr, rs1, context);
|
||||||
self.translate_addi(
|
self.translate_addi(
|
||||||
@@ -773,7 +909,7 @@ impl Asmgen {
|
|||||||
} else {
|
} else {
|
||||||
let rd = get_lhs_register(&value_dtype);
|
let rd = get_lhs_register(&value_dtype);
|
||||||
match ptr_rid {
|
match ptr_rid {
|
||||||
ir::RegisterId::Temp { .. } => {
|
ir::RegisterId::Temp { .. } | ir::RegisterId::Arg { .. } => {
|
||||||
let rs1 = get_rhs_register(ptr_dtype);
|
let rs1 = get_rhs_register(ptr_dtype);
|
||||||
self.translate_load_operand(ptr, rs1, context);
|
self.translate_load_operand(ptr, rs1, context);
|
||||||
context.insts.push(asm::Instruction::IType {
|
context.insts.push(asm::Instruction::IType {
|
||||||
@@ -813,14 +949,18 @@ impl Asmgen {
|
|||||||
|
|
||||||
// 구조체 반환을 위한 공간 예약
|
// 구조체 반환을 위한 공간 예약
|
||||||
if let Some(size) = is_struct(return_type, structs) {
|
if let Some(size) = is_struct(return_type, structs) {
|
||||||
num_int_args += 1;
|
if size > 16 {
|
||||||
struct_stack_allocations += ceil_to_multiple_of_16(size);
|
num_int_args += 1;
|
||||||
|
struct_stack_allocations += ceil_to_multiple_of_16(size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, arg) in args.iter().enumerate() {
|
for (i, arg) in args.iter().enumerate() {
|
||||||
if let Some(size) = is_struct(&arg.dtype(), structs) {
|
if let Some(size) = is_struct(&arg.dtype(), structs) {
|
||||||
let _ = struct_stack_offsets.insert(i, struct_stack_allocations);
|
if size > 16 {
|
||||||
struct_stack_allocations += ceil_to_multiple_of_16(size);
|
let _ = struct_stack_offsets.insert(i, struct_stack_allocations);
|
||||||
|
struct_stack_allocations += ceil_to_multiple_of_16(size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -836,37 +976,39 @@ impl Asmgen {
|
|||||||
// 구조체 인수 복사
|
// 구조체 인수 복사
|
||||||
for (i, arg) in args.iter().enumerate() {
|
for (i, arg) in args.iter().enumerate() {
|
||||||
if let Some(size) = is_struct(&arg.dtype(), structs) {
|
if let Some(size) = is_struct(&arg.dtype(), structs) {
|
||||||
self.translate_addi(
|
if size > 16 {
|
||||||
asm::Register::A0,
|
self.translate_addi(
|
||||||
asm::Register::Sp,
|
asm::Register::A0,
|
||||||
struct_stack_offsets[&i],
|
asm::Register::Sp,
|
||||||
&mut context.insts,
|
struct_stack_offsets[&i],
|
||||||
);
|
&mut context.insts,
|
||||||
match arg {
|
);
|
||||||
ir::Operand::Register { rid, .. } => match rid {
|
match arg {
|
||||||
ir::RegisterId::Temp { bid, iid } => {
|
ir::Operand::Register { rid, .. } => match rid {
|
||||||
self.translate_addi(
|
ir::RegisterId::Temp { bid, iid } => {
|
||||||
asm::Register::A1,
|
self.translate_addi(
|
||||||
asm::Register::S0,
|
asm::Register::A1,
|
||||||
context.stack_offsets[rid],
|
asm::Register::S0,
|
||||||
&mut context.insts,
|
context.stack_offsets[rid],
|
||||||
);
|
&mut context.insts,
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
|
},
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
},
|
}
|
||||||
_ => todo!(),
|
context
|
||||||
|
.insts
|
||||||
|
.push(asm::Instruction::Pseudo(asm::Pseudo::Li {
|
||||||
|
rd: asm::Register::A2,
|
||||||
|
imm: size,
|
||||||
|
}));
|
||||||
|
context
|
||||||
|
.insts
|
||||||
|
.push(asm::Instruction::Pseudo(asm::Pseudo::Call {
|
||||||
|
offset: asm::Label(String::from("memcpy")),
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
context
|
|
||||||
.insts
|
|
||||||
.push(asm::Instruction::Pseudo(asm::Pseudo::Li {
|
|
||||||
rd: asm::Register::A2,
|
|
||||||
imm: size,
|
|
||||||
}));
|
|
||||||
context
|
|
||||||
.insts
|
|
||||||
.push(asm::Instruction::Pseudo(asm::Pseudo::Call {
|
|
||||||
offset: asm::Label(String::from("memcpy")),
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -890,25 +1032,136 @@ impl Asmgen {
|
|||||||
);
|
);
|
||||||
num_float_args += 1;
|
num_float_args += 1;
|
||||||
} else if let Some(size) = is_struct(&dtype, structs) {
|
} else if let Some(size) = is_struct(&dtype, structs) {
|
||||||
self.translate_addi(
|
if size > 16 {
|
||||||
asm::Register::arg(asm::RegisterType::Integer, num_int_args),
|
self.translate_addi(
|
||||||
asm::Register::Sp,
|
asm::Register::arg(asm::RegisterType::Integer, num_int_args),
|
||||||
struct_stack_offsets[&i],
|
asm::Register::Sp,
|
||||||
&mut context.insts,
|
struct_stack_offsets[&i],
|
||||||
);
|
&mut context.insts,
|
||||||
num_int_args += 1;
|
);
|
||||||
|
num_int_args += 1;
|
||||||
|
} else {
|
||||||
|
match arg {
|
||||||
|
ir::Operand::Register { rid, .. } => match rid {
|
||||||
|
ir::RegisterId::Temp { bid, iid } => {
|
||||||
|
self.translate_addi(
|
||||||
|
asm::Register::T5,
|
||||||
|
asm::Register::S0,
|
||||||
|
context.stack_offsets[rid],
|
||||||
|
&mut context.insts,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
|
},
|
||||||
|
_ => todo!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
let struct_name =
|
||||||
|
dtype.get_struct_name().unwrap().as_ref().unwrap().clone();
|
||||||
|
let struct_dtype = structs[&struct_name].clone().unwrap();
|
||||||
|
let fields =
|
||||||
|
struct_dtype.get_struct_fields().unwrap().as_ref().unwrap();
|
||||||
|
|
||||||
|
let mut is_packing = false;
|
||||||
|
let mut packing_start_offset = 0;
|
||||||
|
let mut packing_size = 0;
|
||||||
|
|
||||||
|
for field_dtype in fields {
|
||||||
|
let (offset, _) = struct_dtype
|
||||||
|
.get_offset_struct_field(
|
||||||
|
field_dtype.name().unwrap(),
|
||||||
|
structs,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let field_size = get_dtype_size(&field_dtype, structs);
|
||||||
|
if is_integer(&field_dtype) {
|
||||||
|
if !is_packing {
|
||||||
|
is_packing = true;
|
||||||
|
packing_start_offset = offset;
|
||||||
|
packing_size = field_size;
|
||||||
|
} else {
|
||||||
|
// TODO: 조건 수정 필요
|
||||||
|
if offset
|
||||||
|
== packing_start_offset + (packing_size as usize)
|
||||||
|
&& packing_size + field_size <= 8
|
||||||
|
{
|
||||||
|
packing_size += field_size;
|
||||||
|
} else {
|
||||||
|
context.insts.push(asm::Instruction::IType {
|
||||||
|
instr: asm::IType::LD,
|
||||||
|
rd: asm::Register::arg(
|
||||||
|
asm::RegisterType::Integer,
|
||||||
|
num_int_args,
|
||||||
|
),
|
||||||
|
rs1: asm::Register::T5,
|
||||||
|
imm: asm::Immediate::Value(
|
||||||
|
packing_start_offset as u64,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
num_int_args += 1;
|
||||||
|
packing_start_offset = offset;
|
||||||
|
packing_size = field_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if is_float(&field_dtype) {
|
||||||
|
if is_packing {
|
||||||
|
context.insts.push(asm::Instruction::IType {
|
||||||
|
instr: asm::IType::LD,
|
||||||
|
rd: asm::Register::arg(
|
||||||
|
asm::RegisterType::Integer,
|
||||||
|
num_int_args,
|
||||||
|
),
|
||||||
|
rs1: asm::Register::T5,
|
||||||
|
imm: asm::Immediate::Value(
|
||||||
|
packing_start_offset as u64,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
num_int_args += 1;
|
||||||
|
is_packing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.insts.push(asm::Instruction::IType {
|
||||||
|
instr: asm::IType::load(field_dtype.deref().clone()),
|
||||||
|
rd: asm::Register::arg(
|
||||||
|
asm::RegisterType::FloatingPoint,
|
||||||
|
num_float_args,
|
||||||
|
),
|
||||||
|
rs1: asm::Register::T5,
|
||||||
|
imm: asm::Immediate::Value(packing_start_offset as u64),
|
||||||
|
});
|
||||||
|
num_float_args += 1;
|
||||||
|
} else {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_packing {
|
||||||
|
context.insts.push(asm::Instruction::IType {
|
||||||
|
instr: asm::IType::LD,
|
||||||
|
rd: asm::Register::arg(
|
||||||
|
asm::RegisterType::Integer,
|
||||||
|
num_int_args,
|
||||||
|
),
|
||||||
|
rs1: asm::Register::T5,
|
||||||
|
imm: asm::Immediate::Value(packing_start_offset as u64),
|
||||||
|
});
|
||||||
|
num_int_args += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_struct(return_type, structs).is_some() {
|
if let Some(size) = is_struct(return_type, structs) {
|
||||||
context
|
if size > 16 {
|
||||||
.insts
|
context
|
||||||
.push(asm::Instruction::Pseudo(asm::Pseudo::Mv {
|
.insts
|
||||||
rd: asm::Register::A0,
|
.push(asm::Instruction::Pseudo(asm::Pseudo::Mv {
|
||||||
rs: asm::Register::Sp,
|
rd: asm::Register::A0,
|
||||||
})); // For returned structure
|
rs: asm::Register::Sp,
|
||||||
|
})); // For returned structure
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match callee {
|
match callee {
|
||||||
@@ -945,29 +1198,86 @@ impl Asmgen {
|
|||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
} else if let Some(size) = is_struct(return_type, structs) {
|
} else if let Some(size) = is_struct(return_type, structs) {
|
||||||
self.translate_addi(
|
if size > 16 {
|
||||||
asm::Register::A0,
|
self.translate_addi(
|
||||||
asm::Register::S0,
|
asm::Register::A0,
|
||||||
context.stack_offsets[&rid],
|
asm::Register::S0,
|
||||||
&mut context.insts,
|
context.stack_offsets[&rid],
|
||||||
);
|
&mut context.insts,
|
||||||
self.translate_addi(
|
);
|
||||||
asm::Register::A1,
|
self.translate_addi(
|
||||||
asm::Register::Sp,
|
asm::Register::A1,
|
||||||
0,
|
asm::Register::Sp,
|
||||||
&mut context.insts,
|
0,
|
||||||
);
|
&mut context.insts,
|
||||||
context
|
);
|
||||||
.insts
|
context
|
||||||
.push(asm::Instruction::Pseudo(asm::Pseudo::Li {
|
.insts
|
||||||
rd: asm::Register::A2,
|
.push(asm::Instruction::Pseudo(asm::Pseudo::Li {
|
||||||
imm: size,
|
rd: asm::Register::A2,
|
||||||
}));
|
imm: size,
|
||||||
context
|
}));
|
||||||
.insts
|
context
|
||||||
.push(asm::Instruction::Pseudo(asm::Pseudo::Call {
|
.insts
|
||||||
offset: asm::Label(String::from("memcpy")),
|
.push(asm::Instruction::Pseudo(asm::Pseudo::Call {
|
||||||
}));
|
offset: asm::Label(String::from("memcpy")),
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
let struct_name = return_type
|
||||||
|
.get_struct_name()
|
||||||
|
.unwrap()
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
|
let struct_dtype = structs[&struct_name].clone().unwrap();
|
||||||
|
let fields =
|
||||||
|
struct_dtype.get_struct_fields().unwrap().as_ref().unwrap();
|
||||||
|
let mut num_int_fields = 0;
|
||||||
|
let mut num_float_fields = 0;
|
||||||
|
|
||||||
|
for field_dtype in fields {
|
||||||
|
let (offset, _) = struct_dtype
|
||||||
|
.get_offset_struct_field(field_dtype.name().unwrap(), structs)
|
||||||
|
.unwrap();
|
||||||
|
if is_integer(&field_dtype) {
|
||||||
|
self.translate_addi(
|
||||||
|
asm::Register::T5,
|
||||||
|
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,
|
||||||
|
rs2: asm::Register::arg(
|
||||||
|
asm::RegisterType::Integer,
|
||||||
|
num_int_fields,
|
||||||
|
),
|
||||||
|
imm: asm::Immediate::Value(0),
|
||||||
|
});
|
||||||
|
num_int_fields += 1;
|
||||||
|
} else if is_float(&field_dtype) {
|
||||||
|
self.translate_addi(
|
||||||
|
asm::Register::T5,
|
||||||
|
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,
|
||||||
|
rs2: asm::Register::arg(
|
||||||
|
asm::RegisterType::FloatingPoint,
|
||||||
|
num_float_fields,
|
||||||
|
),
|
||||||
|
imm: asm::Immediate::Value(0),
|
||||||
|
});
|
||||||
|
num_float_fields += 1;
|
||||||
|
} else {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if struct_stack_allocations > 0 {
|
if struct_stack_allocations > 0 {
|
||||||
@@ -987,7 +1297,8 @@ impl Asmgen {
|
|||||||
self.translate_load_operand(value, rs1, context);
|
self.translate_load_operand(value, rs1, context);
|
||||||
|
|
||||||
match (value.dtype(), target_dtype) {
|
match (value.dtype(), target_dtype) {
|
||||||
(ir::Dtype::Int { .. }, ir::Dtype::Int { .. }) => {
|
(ir::Dtype::Int { .. }, ir::Dtype::Int { .. })
|
||||||
|
| (ir::Dtype::Int { .. }, ir::Dtype::Pointer { .. }) => {
|
||||||
self.translate_store_result(&rid, target_dtype.clone(), rs1, context)
|
self.translate_store_result(&rid, target_dtype.clone(), rs1, context)
|
||||||
}
|
}
|
||||||
(ir::Dtype::Float { .. }, ir::Dtype::Float { .. }) => {
|
(ir::Dtype::Float { .. }, ir::Dtype::Float { .. }) => {
|
||||||
@@ -1234,41 +1545,100 @@ impl Asmgen {
|
|||||||
} else if is_float(&dtype) {
|
} else if is_float(&dtype) {
|
||||||
self.translate_load_operand(value, asm::Register::FA0, context);
|
self.translate_load_operand(value, asm::Register::FA0, context);
|
||||||
} else if let Some(size) = is_struct(&dtype, structs) {
|
} else if let Some(size) = is_struct(&dtype, structs) {
|
||||||
context.insts.push(asm::Instruction::IType {
|
if size > 16 {
|
||||||
instr: asm::IType::load(ir::Dtype::pointer(ir::Dtype::unit())), // TODO: ok?
|
context.insts.push(asm::Instruction::IType {
|
||||||
rd: asm::Register::A0,
|
instr: asm::IType::load(ir::Dtype::pointer(ir::Dtype::unit())), // TODO: ok?
|
||||||
rs1: asm::Register::S0,
|
rd: asm::Register::A0,
|
||||||
imm: asm::Immediate::Value(!24 + 1),
|
rs1: asm::Register::S0,
|
||||||
});
|
imm: asm::Immediate::Value(!24 + 1),
|
||||||
match value {
|
});
|
||||||
ir::Operand::Constant(constant) => match constant {
|
match value {
|
||||||
ir::Constant::Undef { .. } => (), // DO nothing
|
ir::Operand::Constant(constant) => match constant {
|
||||||
|
ir::Constant::Undef { .. } => (), // DO nothing
|
||||||
|
_ => todo!(),
|
||||||
|
},
|
||||||
|
ir::Operand::Register { rid, .. } => match rid {
|
||||||
|
ir::RegisterId::Temp { bid, iid } => {
|
||||||
|
self.translate_addi(
|
||||||
|
asm::Register::A1,
|
||||||
|
asm::Register::S0,
|
||||||
|
context.stack_offsets[rid],
|
||||||
|
&mut context.insts,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
|
},
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
},
|
}
|
||||||
ir::Operand::Register { rid, .. } => match rid {
|
context
|
||||||
ir::RegisterId::Temp { bid, iid } => {
|
.insts
|
||||||
self.translate_addi(
|
.push(asm::Instruction::Pseudo(asm::Pseudo::Li {
|
||||||
asm::Register::A1,
|
rd: asm::Register::A2,
|
||||||
asm::Register::S0,
|
imm: size,
|
||||||
context.stack_offsets[rid],
|
}));
|
||||||
&mut context.insts,
|
context
|
||||||
);
|
.insts
|
||||||
|
.push(asm::Instruction::Pseudo(asm::Pseudo::Call {
|
||||||
|
offset: asm::Label(String::from("memcpy")),
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
match value {
|
||||||
|
ir::Operand::Constant(constant) => match constant {
|
||||||
|
ir::Constant::Undef { .. } => (), // DO nothing
|
||||||
|
_ => todo!(),
|
||||||
|
},
|
||||||
|
ir::Operand::Register { rid, .. } => match rid {
|
||||||
|
ir::RegisterId::Temp { bid, iid } => {
|
||||||
|
self.translate_addi(
|
||||||
|
asm::Register::T5,
|
||||||
|
asm::Register::S0,
|
||||||
|
context.stack_offsets[rid],
|
||||||
|
&mut context.insts,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
|
},
|
||||||
|
_ => todo!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
let struct_name =
|
||||||
|
dtype.get_struct_name().unwrap().as_ref().unwrap().clone();
|
||||||
|
let struct_dtype = structs[&struct_name].clone().unwrap();
|
||||||
|
let fields = struct_dtype.get_struct_fields().unwrap().as_ref().unwrap();
|
||||||
|
let mut num_int_fields = 0;
|
||||||
|
let mut num_float_fields = 0;
|
||||||
|
|
||||||
|
for field_dtype in fields {
|
||||||
|
let (offset, _) = struct_dtype
|
||||||
|
.get_offset_struct_field(field_dtype.name().unwrap(), structs)
|
||||||
|
.unwrap();
|
||||||
|
if is_integer(&field_dtype) {
|
||||||
|
context.insts.push(asm::Instruction::IType {
|
||||||
|
instr: asm::IType::load(field_dtype.deref().clone()),
|
||||||
|
rd: asm::Register::arg(
|
||||||
|
asm::RegisterType::Integer,
|
||||||
|
num_int_fields,
|
||||||
|
),
|
||||||
|
rs1: asm::Register::T5,
|
||||||
|
imm: asm::Immediate::Value(offset as u64),
|
||||||
|
});
|
||||||
|
num_int_fields += 1;
|
||||||
|
} else if is_float(&field_dtype) {
|
||||||
|
context.insts.push(asm::Instruction::IType {
|
||||||
|
instr: asm::IType::load(field_dtype.deref().clone()),
|
||||||
|
rd: asm::Register::arg(
|
||||||
|
asm::RegisterType::FloatingPoint,
|
||||||
|
num_float_fields,
|
||||||
|
),
|
||||||
|
rs1: asm::Register::T5,
|
||||||
|
imm: asm::Immediate::Value(offset as u64),
|
||||||
|
});
|
||||||
|
num_float_fields += 1;
|
||||||
|
} else {
|
||||||
|
todo!()
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
}
|
||||||
},
|
|
||||||
_ => todo!(),
|
|
||||||
}
|
}
|
||||||
context
|
|
||||||
.insts
|
|
||||||
.push(asm::Instruction::Pseudo(asm::Pseudo::Li {
|
|
||||||
rd: asm::Register::A2,
|
|
||||||
imm: size,
|
|
||||||
}));
|
|
||||||
context
|
|
||||||
.insts
|
|
||||||
.push(asm::Instruction::Pseudo(asm::Pseudo::Call {
|
|
||||||
offset: asm::Label(String::from("memcpy")),
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
self.translate_epilogue(context);
|
self.translate_epilogue(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2126,7 +2126,12 @@ impl IrgenFunc<'_> {
|
|||||||
lhs_dtype
|
lhs_dtype
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => todo!("merge_dtype"),
|
(&ir::Dtype::Pointer { .. }, &ir::Dtype::Int { .. }) => lhs_dtype,
|
||||||
|
(&ir::Dtype::Int { .. }, &ir::Dtype::Pointer { .. }) => rhs_dtype,
|
||||||
|
_ => {
|
||||||
|
println!("{:?} {:?}", lhs_dtype, rhs_dtype);
|
||||||
|
todo!("merge_dtype")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user