Skip to content

Improved backend by refactoring code and optimizing output #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 14, 2024
Merged
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Cargo.lock
**/*.rs.bk


/tests/benchmarks/*.s
# /tests/benchmarks/*.s
/tests/exec/*.s
/tests/exec-fail/*.s
/tests/dependancies/good/main.s
Expand Down
15 changes: 13 additions & 2 deletions bench.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
#!/bin/sh
#!/bin/bash

shopt -s nullglob

if [[ $OSTYPE == 'darwin'* ]]; then
GCC=gcc
fi

if [[ $OSTYPE == 'linux'* ]]; then
GCC="gcc -no-pie -z noexecstack"
fi


for f in tests/benchmarks/*.rs; do
echo "$f"
file=`basename $f .rs`

./target/debug/sam_rust_compiler tests/benchmarks/$file.rs >> /dev/null
gcc tests/benchmarks/$file.s >> /dev/null
$GCC tests/benchmarks/$file.s >> /dev/null
rustc -O tests/benchmarks/$file.rs >> /dev/null 2>&1
echo " -- $file with rustc -O"
echo " -- rustc -O" > tests/benchmarks/$file.perf
Expand Down
116 changes: 116 additions & 0 deletions src/ast/asm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
use super::low_level_repr::Value;
use write_x86_64::*;

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Registers {
RegA,
RegC,
RegD,
}

impl Registers {
pub fn q(&self) -> reg::RegQ {
match self {
Self::RegA => RAX,
Self::RegC => RCX,
Self::RegD => RDX,
}
}

pub fn l(&self) -> reg::RegL {
match self {
Self::RegA => EAX,
Self::RegC => ECX,
Self::RegD => EDX,
}
}

pub fn w(&self) -> reg::RegW {
match self {
Self::RegA => AX,
Self::RegC => CX,
Self::RegD => DX,
}
}

pub fn b(&self) -> reg::RegB {
match self {
Self::RegA => AL,
Self::RegC => CL,
Self::RegD => DL,
}
}
}

impl Value {
pub fn q(&self) -> reg::Operand<reg::RegQ> {
match self {
Value::SInt(i, _) => immq(*i as i64),
Value::UInt(i, _) => immq(*i as i64),
Value::Bool(true) => immq(1),
Value::Bool(false) => immq(0),
}
}

pub fn l(&self) -> reg::Operand<reg::RegL> {
match self {
Value::SInt(i, _) => imml(*i as i32),
Value::UInt(i, _) => imml(*i as i32),
Value::Bool(true) => imml(1),
Value::Bool(false) => imml(0),
}
}

pub fn w(&self) -> reg::Operand<reg::RegW> {
match self {
Value::SInt(i, _) => immw(*i as i16),
Value::UInt(i, _) => immw(*i as i16),
Value::Bool(true) => immw(1),
Value::Bool(false) => immw(0),
}
}

pub fn b(&self) -> reg::Operand<reg::RegB> {
match self {
Value::SInt(i, _) => immb(*i as i8),
Value::UInt(i, _) => immb(*i as i8),
Value::Bool(true) => immb(1),
Value::Bool(false) => immb(0),
}
}
}

pub enum ImmOrReg {
V(Value),
R(Registers),
}

impl ImmOrReg {
pub fn q(&self) -> reg::Operand<reg::RegQ> {
match self {
Self::R(r) => reg!(r.q()),
Self::V(v) => v.q(),
}
}

pub fn l(&self) -> reg::Operand<reg::RegL> {
match self {
Self::R(r) => reg!(r.l()),
Self::V(v) => v.l(),
}
}

pub fn w(&self) -> reg::Operand<reg::RegW> {
match self {
Self::R(r) => reg!(r.w()),
Self::V(v) => v.w(),
}
}

pub fn b(&self) -> reg::Operand<reg::RegB> {
match self {
Self::R(r) => reg!(r.b()),
Self::V(v) => v.b(),
}
}
}
44 changes: 8 additions & 36 deletions src/ast/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,14 @@ impl Sizes {
}
}

pub fn max_imm_size(&self) -> usize {
match self {
Self::S8 => 8,
Self::S16 => 16,
Self::S32 | Self::S64 | Self::SUsize => 32,
}
}

pub fn max_sval(&self) -> i64 {
match self {
Self::S8 => (-1i8) as i64,
Expand Down Expand Up @@ -617,39 +625,3 @@ impl ErrorReporter {
std::process::exit(1);
}
}

#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
pub enum TypedBinop {
Add(Sizes),
Mul(bool, Sizes),
Sub(Sizes),
Div(bool, Sizes),
Mod(bool, Sizes),
LAnd,
LOr,
And(Sizes),
Or(Sizes),
Shl(Sizes),
Shr(Sizes),
Eq(Sizes),
Neq(Sizes),
Lower(bool, Sizes),
LowerEq(bool, Sizes),
Greater(bool, Sizes),
GreaterEq(bool, Sizes),
}

impl TypedBinop {
pub fn can_unary(&self) -> bool {
match self {
Self::LAnd | Self::LOr => false,
_ => true,
}
}
}

#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
pub enum TypedUnaop {
Not(Sizes),
Neg(Sizes),
}
22 changes: 19 additions & 3 deletions src/ast/low_level_repr.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::common::{self, PathUL};
use super::operators::{TBinop, TUnaop};

#[derive(Debug)]
pub struct File {
Expand Down Expand Up @@ -92,6 +93,21 @@ impl Value {
Self::UInt(u, _) => *u as i64,
}
}

pub fn size(&self) -> common::Sizes {
match self {
Self::Bool(_) => common::Sizes::S8,
Self::SInt(_, s) | Self::UInt(_, s) => *s,
}
}

pub fn valid(&self) -> bool {
match self {
Self::Bool(_) => true,
Self::SInt(i, s) => i.abs() < 1 << (s.max_imm_size() - 1),
Self::UInt(i, s) => *i < 1 << s.max_imm_size(),
}
}
}

#[derive(Clone, Copy, Debug)]
Expand All @@ -111,13 +127,13 @@ impl Pos {

#[derive(Debug)]
pub enum UnaOp {
Unary(common::TypedUnaop),
Binary(common::TypedBinop, Value, Pos)
Unary(TUnaop),
Binary(TBinop, Value, Pos),
}

#[derive(Debug)]
pub enum ExprInner {
BinOp(common::TypedBinop, Expr, Expr),
BinOp(TBinop, Expr, Expr),
Bloc(Bloc),
BuildStruct(usize /* size */, Vec<(usize, Expr)>),
Coercion(Expr, common::BuiltinType, common::BuiltinType),
Expand Down
2 changes: 2 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
pub mod asm;
pub mod can_write;
pub mod common;
pub mod low_level_repr;
pub mod operators;
pub mod rust;
pub mod typed_rust;
128 changes: 128 additions & 0 deletions src/ast/operators.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
use super::common::Sizes;

#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
pub enum LArith {
Add(Sizes),
Sub(Sizes),
And(Sizes),
Or(Sizes),
}

impl LArith {
pub fn commutes(&self) -> bool {
match self {
Self::Sub(_) => false,
_ => true,
}
}
}

#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
pub enum CmpDesc {
Eq,
Neq,
Lower,
LowerEq,
Greater,
GreaterEq,
}

impl CmpDesc {
fn rev(self) -> Self {
match self {
Self::Eq => Self::Eq,
Self::Neq => Self::Neq,
Self::Lower => Self::Greater,
Self::LowerEq => Self::LowerEq,
Self::Greater => Self::Lower,
Self::GreaterEq => Self::LowerEq,
}
}
}

#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
pub struct Cmp {
pub cmp: CmpDesc,
pub signed: bool,
pub size: Sizes,
}

impl Cmp {
pub fn cond_rev(mut self, b: bool) -> Self {
if b {
self.cmp = self.cmp.rev()
}
self
}

pub fn new(cmp: CmpDesc, signed: bool, size: Sizes) -> Self {
Self { cmp, signed, size }
}

pub fn eq(size: Sizes) -> Self {
Self {
cmp: CmpDesc::Eq,
signed: false,
size,
}
}

pub fn neq(size: Sizes) -> Self {
Self {
cmp: CmpDesc::Neq,
signed: false,
size,
}
}
}

#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
pub enum HArithDesc {
Div,
Mod,
Mul,
}

#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
pub struct HArith {
pub dm: HArithDesc,
pub signed: bool,
pub size: Sizes,
}

impl HArith {
pub fn new(dm: HArithDesc, signed: bool, size: Sizes) -> Self {
Self { dm, signed, size }
}
}

#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
pub enum Logic {
LAnd,
LOr,
}

#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
pub enum TBinop {
LArith(LArith),
Cmp(Cmp),
HArith(HArith),
Logic(Logic),
Shl(Sizes),
Shr(Sizes),
}

impl TBinop {
pub fn can_unary(&self) -> bool {
match self {
Self::Logic(_) => false,
_ => true,
}
}
}

#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
pub enum TUnaop {
Not(Sizes),
Neg(Sizes),
}
Loading
Loading