Update skeleton

This commit is contained in:
Jeehoon Kang
2020-06-01 21:51:16 +09:00
parent 4c850d5801
commit 1c0c9a5dbc
12 changed files with 807 additions and 181 deletions

View File

@@ -48,8 +48,14 @@ impl WriteLine for Function {
}
impl WriteLine for Variable {
fn write_line(&self, _indent: usize, _write: &mut dyn Write) -> Result<()> {
todo!()
fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> {
writeln!(write, "{}:", self.label.0)?;
for directive in &self.directives {
write_indent(indent + INDENT, write)?;
writeln!(write, "{}", directive.write_string())?;
}
Ok(())
}
}
@@ -75,10 +81,27 @@ impl WriteString for Directive {
Self::Type(symbol, symbol_type) => {
format!(".type\t{}, {}", symbol.0, symbol_type.write_string())
}
Self::Section(section_type) => format!(".section\t{}", section_type.write_string()),
Self::Byte(value) => format!(".byte\t{:#x?}", value),
Self::Half(value) => format!(".half\t{:#x?}", value),
Self::Word(value) => format!(".word\t{:#x?}", value),
Self::Quad(value) => format!(".quad\t{:#x?}", value),
}
}
}
impl WriteString for SectionType {
fn write_string(&self) -> String {
match self {
Self::Text => ".text",
Self::Data => ".data",
Self::Rodata => ".rodata",
Self::Bss => ".bss",
}
.to_string()
}
}
impl WriteString for SymbolType {
fn write_string(&self) -> String {
match self {
@@ -97,25 +120,39 @@ impl WriteString for Instruction {
rd,
rs1,
rs2,
} => format!(
"{}\t{},{},{}",
instr.write_string(),
rd.write_string(),
rs1.write_string(),
rs2.write_string()
),
} => {
let rounding_mode = if let RType::FcvtFloatToInt { .. } = instr {
",rtz"
} else {
""
}
.to_string();
format!(
"{}\t{},{}{}{}",
instr.write_string(),
rd.write_string(),
rs1.write_string(),
if let Some(rs2) = rs2 {
format!(",{}", rs2.write_string())
} else {
"".to_string()
},
rounding_mode
)
}
Self::IType {
instr,
rd,
rs1,
imm,
} => {
if let IType::Load(_) = instr {
if let IType::Load { .. } = instr {
format!(
"{}\t{},{}({})",
instr.write_string(),
rd.write_string(),
imm,
imm.write_string(),
rs1.write_string()
)
} else {
@@ -124,7 +161,7 @@ impl WriteString for Instruction {
instr.write_string(),
rd.write_string(),
rs1.write_string(),
imm
imm.write_string(),
)
}
}
@@ -137,7 +174,7 @@ impl WriteString for Instruction {
"{}\t{},{}({})",
instr.write_string(),
rs2.write_string(),
imm.to_string(),
imm.write_string(),
rs1.write_string()
),
Self::BType {
@@ -152,6 +189,12 @@ impl WriteString for Instruction {
rs2.write_string(),
imm.0,
),
Self::UType { instr, rd, imm } => format!(
"{}\t{}, {}",
instr.write_string(),
rd.write_string(),
imm.write_string(),
),
Self::Pseudo(pseudo) => pseudo.write_string(),
}
}
@@ -162,14 +205,101 @@ impl WriteString for RType {
match self {
Self::Add(data_size) => format!("add{}", data_size.write_string()),
Self::Sub(data_size) => format!("sub{}", data_size.write_string()),
Self::Sll(data_size) => format!("sll{}", data_size.write_string()),
Self::Srl(data_size) => format!("srl{}", data_size.write_string()),
Self::Sra(data_size) => format!("srl{}", data_size.write_string()),
Self::Mul(data_size) => format!("mul{}", data_size.write_string()),
Self::Div(data_size, is_signed) => format!(
Self::Div {
data_size,
is_signed,
} => format!(
"div{}{}",
if *is_signed { "" } else { "u" },
data_size.write_string()
),
Self::Slt(is_signed) => format!("slt{}", if *is_signed { "" } else { "u" }),
Self::Rem {
data_size,
is_signed,
} => format!(
"rem{}{}",
if *is_signed { "" } else { "u" },
data_size.write_string()
),
Self::Slt { is_signed } => format!("slt{}", if *is_signed { "" } else { "u" }),
Self::Xor => "xor".to_string(),
Self::Or => "or".to_string(),
Self::And => "and".to_string(),
Self::Fadd(data_size) => format!("fadd.{}", data_size.write_string()),
Self::Fsub(data_size) => format!("fsub.{}", data_size.write_string()),
Self::Fmul(data_size) => format!("fmul.{}", data_size.write_string()),
Self::Fdiv(data_size) => format!("fdiv.{}", data_size.write_string()),
Self::Feq(data_size) => format!("feq.{}", data_size.write_string()),
Self::Flt(data_size) => format!("flt.{}", data_size.write_string()),
Self::FmvFloatToInt { float_data_size } => {
assert!(float_data_size.is_floating_point());
format!(
"fmv.x.{}",
if *float_data_size == DataSize::SinglePrecision {
"w"
} else {
"d"
}
)
}
Self::FmvIntToFloat { float_data_size } => {
assert!(float_data_size.is_floating_point());
format!(
"fmv.{}.x",
if *float_data_size == DataSize::SinglePrecision {
"w"
} else {
"d"
}
)
}
Self::FcvtFloatToInt {
float_data_size,
int_data_size,
is_signed,
} => {
assert!(float_data_size.is_floating_point());
format!(
"fcvt.{}{}.{}",
if let Some(int_data_size) = int_data_size {
assert_eq!(*int_data_size, DataSize::Word);
"w"
} else {
"l"
}
.to_string(),
if *is_signed { "" } else { "u" },
float_data_size.write_string()
)
}
Self::FcvtIntToFloat {
int_data_size,
float_data_size,
is_signed,
} => {
assert!(float_data_size.is_floating_point());
format!(
"fcvt.{}.{}{}",
float_data_size.write_string(),
if let Some(int_data_size) = int_data_size {
assert_eq!(*int_data_size, DataSize::Word);
"w"
} else {
"l"
}
.to_string(),
if *is_signed { "" } else { "u" }
)
}
Self::FcvtFloatToFloat { from, to } => {
assert!(from.is_floating_point());
assert!(to.is_floating_point());
format!("fcvt.{}.{}", to.write_string(), from.write_string())
}
}
}
}
@@ -177,8 +307,30 @@ impl WriteString for RType {
impl WriteString for IType {
fn write_string(&self) -> String {
match self {
Self::Load(data_size) => format!("l{}", data_size.write_string()),
Self::Load {
data_size,
is_signed,
} => {
if data_size.is_integer() {
format!(
"l{}{}",
data_size.write_string(),
if *is_signed { "" } else { "u" }
)
} else {
format!(
"fl{}",
if *data_size == DataSize::SinglePrecision {
"w"
} else {
"d"
}
)
}
}
Self::Addi(data_size) => format!("addi{}", data_size.write_string()),
Self::Xori => "xori".to_string(),
Self::Ori => "ori".to_string(),
Self::Andi => "andi".to_string(),
Self::Slli => "slli".to_string(),
Self::Srli => "srli".to_string(),
@@ -189,7 +341,20 @@ impl WriteString for IType {
impl WriteString for SType {
fn write_string(&self) -> String {
match self {
Self::Store(data_size) => format!("s{}", data_size.write_string()),
Self::Store(data_size) => {
if data_size.is_integer() {
format!("s{}", data_size.write_string())
} else {
format!(
"fs{}",
if *data_size == DataSize::SinglePrecision {
"w"
} else {
"d"
}
)
}
}
}
}
}
@@ -199,8 +364,16 @@ impl WriteString for BType {
match self {
Self::Beq => "beq".to_string(),
Self::Bne => "bne".to_string(),
Self::Blt(is_signed) => format!("blt{}", if *is_signed { "" } else { "u" }),
Self::Bge(is_signed) => format!("bge{}", if *is_signed { "" } else { "u" }),
Self::Blt { is_signed } => format!("blt{}", if *is_signed { "" } else { "u" }),
Self::Bge { is_signed } => format!("bge{}", if *is_signed { "" } else { "u" }),
}
}
}
impl WriteString for UType {
fn write_string(&self) -> String {
match self {
Self::Lui => "lui".to_string(),
}
}
}
@@ -208,9 +381,9 @@ impl WriteString for BType {
impl WriteString for Pseudo {
fn write_string(&self) -> String {
match self {
Self::Li { rd, imm } => format!("li\t{},{}", rd.write_string(), imm),
Self::Mv { rs, rd } => format!("mv\t{},{}", rd.write_string(), rs.write_string()),
Self::Neg { data_size, rs, rd } => format!(
Self::Li { rd, imm } => format!("li\t{},{:#x?}", rd.write_string(), imm),
Self::Mv { rd, rs } => format!("mv\t{},{}", rd.write_string(), rs.write_string()),
Self::Neg { data_size, rd, rs } => format!(
"neg{}\t{},{}",
data_size.write_string(),
rd.write_string(),
@@ -219,15 +392,44 @@ impl WriteString for Pseudo {
Self::SextW { rs, rd } => {
format!("sext.w\t{},{}", rd.write_string(), rs.write_string())
}
Self::Seqz { rs, rd } => format!("seqz\t{},{}", rd.write_string(), rs.write_string()),
Self::Seqz { rd, rs } => format!("seqz\t{},{}", rd.write_string(), rs.write_string()),
Self::Snez { rd, rs } => format!("snez\t{},{}", rd.write_string(), rs.write_string()),
Self::Fneg { data_size, rd, rs } => format!(
"fneg.{}\t{},{}",
data_size.write_string(),
rd.write_string(),
rs.write_string()
),
Self::J { offset } => format!("j\t{}", offset.0),
Self::Jr { rs } => format!("jr\t{}", rs.write_string()),
Self::Jalr { rs } => format!("jalr\t{}", rs.write_string()),
Self::Ret => "ret".to_string(),
Self::Call { offset } => format!("call\t{}", offset.0),
}
}
}
impl WriteString for Immediate {
fn write_string(&self) -> String {
match self {
Self::Value(value) => format!("{:#x?}", value),
Self::Relocation { relocation, symbol } => {
format!("{}({})", relocation.write_string(), symbol.0)
}
}
}
}
impl WriteString for RelocationFunction {
fn write_string(&self) -> String {
match self {
Self::HI20 => "%hi",
Self::LO12 => "%lo",
}
.to_string()
}
}
impl WriteString for DataSize {
fn write_string(&self) -> String {
match self {
@@ -235,6 +437,8 @@ impl WriteString for DataSize {
Self::Half => "h",
Self::Word => "w",
Self::Double => "d",
Self::SinglePrecision => "s",
Self::DoublePrecision => "d",
}
.to_string()
}
@@ -248,9 +452,33 @@ impl WriteString for Register {
Self::Sp => "sp".to_string(),
Self::Gp => "gp".to_string(),
Self::Tp => "tp".to_string(),
Self::Temp(id) => format!("t{}", id),
Self::Saved(id) => format!("s{}", id),
Self::Arg(id) => format!("a{}", id),
Self::Temp(registr_type, id) => format!(
"{}t{}",
if *registr_type == RegisterType::FloatingPoint {
"f"
} else {
""
},
id
),
Self::Saved(registr_type, id) => format!(
"{}s{}",
if *registr_type == RegisterType::FloatingPoint {
"f"
} else {
""
},
id
),
Self::Arg(registr_type, id) => format!(
"{}a{}",
if *registr_type == RegisterType::FloatingPoint {
"f"
} else {
""
},
id
),
}
}
}