Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/analyze/types.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::generate::generate::RegSize;
use crate::generate::registers::RegSize;

use super::analyze::{Func, Struct};

Expand Down
28 changes: 28 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use crate::analyze::expr::ConvExprKind;
use crate::analyze::expr::FuncCallTargetKind;
use crate::analyze::types::Type;
use crate::analyze::variables::GVar;
use crate::generate::register_allocator::data_location::DataLocation;
use crate::generate::register_allocator::data_location::RegId;
use crate::preprocess::tokenkind::TokenKind as PreprocessTokenKind;
use crate::tokenize::debug_infos::DebugInfo;
use crate::tokenize::debug_infos::Position;
Expand Down Expand Up @@ -254,6 +256,20 @@ impl CompileError {
GenerateErrorKind::UnexpectedTypeSize(status),
))
}

pub fn new_register_assign_error(
try_assign_id: RegId,
to: DataLocation,
message: impl ToString,
) -> Self {
Self::new(CompileErrorKind::GenerateError(
GenerateErrorKind::LocationAssignError {
try_assign_id,
to,
message: message.to_string(),
},
))
}
}

#[derive(PartialEq, Eq, Clone, Debug)]
Expand Down Expand Up @@ -521,6 +537,13 @@ impl Debug for CompileError {
)) => {
writeln!(f, "this type size is unexpected. size: {}", size)?;
}
GenerateError(GenerateErrorKind::LocationAssignError {
try_assign_id,
to,
message,
}) => {
writeln!(f, "INTERNAL COMPILER(Register Allocator Error): try to assign RegId: {:?} to Register: {:?}, but failed.\n{}", try_assign_id, to, message)?;
}
Unimplemented(Some(debug_info), msg) => {
error_at(vec![debug_info.clone()], f)?;
writeln!(f, "{}", msg)?;
Expand Down Expand Up @@ -617,6 +640,11 @@ pub enum GenerateErrorKind {
UnexpectedTypeSize(UnexpectedTypeSizeStatus),
LeftValueError(ConvExpr),
DerefError(ConvExpr),
LocationAssignError {
try_assign_id: RegId,
to: DataLocation,
message: String,
},
}

#[derive(PartialEq, Eq, Clone, Debug)]
Expand Down
2 changes: 2 additions & 0 deletions src/generate.rs
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
pub mod generate;
pub mod register_allocator;
pub mod registers;
231 changes: 2 additions & 229 deletions src/generate/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use crate::{
unimplemented_err,
};

use super::registers::{RegKind, RegOrLit, RegSize};

#[derive(Debug, Clone)]
pub struct Generator {
label: usize,
Expand Down Expand Up @@ -1230,232 +1232,3 @@ impl Generator {
self.label
}
}

#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Debug)]
pub enum RegOrLit {
Reg(RegKind),
Lit(isize),
}

impl RegOrLit {
pub fn size_to_reg_name(&self, size: RegSize) -> String {
match size {
RegSize::Byte => self.byte(),
RegSize::Dword => self.dword(),
RegSize::Qword => self.qword(),
}
}

pub fn byte(&self) -> String {
match self {
RegOrLit::Reg(reg) => reg.byte().to_string(),
RegOrLit::Lit(num) => num.to_string(),
}
}

pub fn dword(&self) -> String {
match self {
RegOrLit::Reg(reg) => reg.dword().to_string(),
RegOrLit::Lit(num) => num.to_string(),
}
}

pub fn qword(&self) -> String {
match self {
RegOrLit::Reg(reg) => reg.qword().to_string(),
RegOrLit::Lit(num) => num.to_string(),
}
}
}

impl ToString for RegOrLit {
fn to_string(&self) -> String {
match self {
RegOrLit::Reg(reg) => reg.to_string(),
RegOrLit::Lit(num) => num.to_string(),
}
}
}

#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Debug)]
pub enum RegKind {
Rax,
Rdi,
Rsi,
Rdx,
Rcx,
Rbp,
Rsp,
R8,
R9,
R10,
R11,
R12,
R13,
R14,
R15,
}

impl ToString for RegKind {
fn to_string(&self) -> String {
match self {
RegKind::Rax => "rax",
RegKind::Rdi => "rdi",
RegKind::Rsi => "rsi",
RegKind::Rdx => "rdx",
RegKind::Rcx => "rcx",
RegKind::Rbp => "rbp",
RegKind::Rsp => "rsp",
RegKind::R8 => "r8",
RegKind::R9 => "r9",
RegKind::R10 => "r10",
RegKind::R11 => "r11",
RegKind::R12 => "r12",
RegKind::R13 => "r13",
RegKind::R14 => "r14",
RegKind::R15 => "r15",
}
.to_string()
}
}

impl TryFrom<&str> for RegKind {
type Error = ();

fn try_from(value: &str) -> Result<Self, Self::Error> {
Ok(match value {
"rax" => RegKind::Rax,
"rdi" => RegKind::Rdi,
"rsi" => RegKind::Rsi,
"rdx" => RegKind::Rdx,
"rcx" => RegKind::Rcx,
"r8" => RegKind::R8,
"r9" => RegKind::R9,
_ => return Err(()),
})
}
}

#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Debug)]
pub enum RegSize {
Byte,
Dword,
Qword,
}

impl RegSize {
pub const fn try_new(size: usize) -> Option<Self> {
Some(match size {
1 => Self::Byte,
4 => Self::Dword,
8 => Self::Qword,
_ => return None,
})
}

// clippy complains about this, but it's wrong
#[allow(clippy::missing_const_for_fn)]
pub fn try_new_with_error(size: usize, expr: ConvExpr) -> Result<Self, CompileError> {
Ok(match size {
1 => Self::Byte,
4 => Self::Dword,
8 => Self::Qword,
_ => {
return Err(CompileError::new_type_size_error(
UnexpectedTypeSizeStatus::Expr(expr),
));
}
})
}
}

impl AsRef<str> for RegSize {
fn as_ref(&self) -> &str {
match self {
RegSize::Byte => "BYTE",
RegSize::Dword => "DWORD",
RegSize::Qword => "QWORD",
}
}
}

impl RegSize {
pub const fn size_to_name(size: usize) -> Option<RegSize> {
match size {
1 => Some(Self::Byte),
4 => Some(Self::Dword),
8 => Some(Self::Qword),
_ => None,
}
}
}

impl RegKind {
pub const fn size_to_reg_name(&self, size: RegSize) -> &str {
match size {
RegSize::Byte => self.byte(),
RegSize::Dword => self.dword(),
RegSize::Qword => self.qword(),
}
}

pub const fn byte(&self) -> &str {
match self {
RegKind::Rax => "al",
RegKind::Rdi => "dil",
RegKind::Rsi => "sil",
RegKind::Rdx => "dl",
RegKind::Rcx => "cl",
RegKind::Rbp => "bpl",
RegKind::Rsp => "spl",
RegKind::R8 => "r8b",
RegKind::R9 => "r9b",
RegKind::R10 => "r10b",
RegKind::R11 => "r11b",
RegKind::R12 => "r12b",
RegKind::R13 => "r13b",
RegKind::R14 => "r14b",
RegKind::R15 => "r15b",
}
}

pub const fn dword(&self) -> &str {
match self {
RegKind::Rax => "eax",
RegKind::Rdi => "edi",
RegKind::Rsi => "esi",
RegKind::Rdx => "edx",
RegKind::Rcx => "ecx",
RegKind::Rbp => "ebp",
RegKind::Rsp => "esp",
RegKind::R8 => "r8d",
RegKind::R9 => "r9d",
RegKind::R10 => "r10d",
RegKind::R11 => "r11d",
RegKind::R12 => "r12d",
RegKind::R13 => "r13d",
RegKind::R14 => "r14d",
RegKind::R15 => "r15d",
}
}

pub const fn qword(&self) -> &str {
match self {
RegKind::Rax => "rax",
RegKind::Rdi => "rdi",
RegKind::Rsi => "rsi",
RegKind::Rdx => "rdx",
RegKind::Rcx => "rcx",
RegKind::Rbp => "rbp",
RegKind::Rsp => "rsp",
RegKind::R8 => "r8",
RegKind::R9 => "r9",
RegKind::R10 => "r10",
RegKind::R11 => "r11",
RegKind::R12 => "r12",
RegKind::R13 => "r13",
RegKind::R14 => "r14",
RegKind::R15 => "r15",
}
}
}
7 changes: 7 additions & 0 deletions src/generate/register_allocator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pub mod allocated_register_table;
pub mod allocator;
pub mod data_location;
pub mod location_map;
pub mod regid_entry;
pub mod stack_depth_table;
pub mod stacks;
Loading