Skip to content

Commit 25db06d

Browse files
committed
Better type support. Some casts now work. Some if's and match'es now work.
1 parent c894d2a commit 25db06d

File tree

6 files changed

+264
-266
lines changed

6 files changed

+264
-266
lines changed

makefile

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
TEST_DIR = "test"
2-
CODEGEN_BACKEND = target/debug/librustc_codegen_clr.so
2+
CODEGEN_BACKEND = ../target/debug/librustc_codegen_clr.so
33
RUSTC = rustc
44
RUST_FLAGS = --crate-type lib
5-
test: build_backend compile_simple_file
6-
compile_simple_file:
7-
rustc $(RUST_FLAGS) -O -Z codegen-backend=$(CODEGEN_BACKEND) test/identity.rs
5+
test: build_backend identy binops casts types ifs
6+
identy:
7+
cd test && rustc $(RUST_FLAGS) -O -Z codegen-backend=$(CODEGEN_BACKEND) identity.rs
8+
binops:
9+
cd test && rustc $(RUST_FLAGS) -O -Z codegen-backend=$(CODEGEN_BACKEND) binops.rs
10+
casts:
11+
cd test && rustc $(RUST_FLAGS) -O -Z codegen-backend=$(CODEGEN_BACKEND) casts.rs
12+
types:
13+
cd test && rustc $(RUST_FLAGS) -O -Z codegen-backend=$(CODEGEN_BACKEND) types.rs
14+
branches:
15+
cd test && rustc $(RUST_FLAGS) -O -Z codegen-backend=$(CODEGEN_BACKEND) branches.rs
816
build_backend:
917
cargo build
1018

src/assembly.rs

+18-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::{FunctionSignature,CLRMethod};
21
use crate::IString;
2+
use crate::{CLRMethod, FunctionSignature};
33
use rustc_middle::{
44
mir::mono::MonoItem,
55
ty::{Instance, ParamEnv, TyCtxt},
@@ -9,10 +9,9 @@ pub(crate) struct Assembly {
99
name: IString,
1010
}
1111
impl Assembly {
12-
1312
pub(crate) fn into_il_ir(&self) -> IString {
1413
let mut methods = String::new();
15-
for method in &self.methods{
14+
for method in &self.methods {
1615
methods.push_str(&method.into_il_ir());
1716
}
1817
let methods = format!(".class {name} {{{methods}}}", name = self.name);
@@ -22,33 +21,39 @@ impl Assembly {
2221
impl Assembly {
2322
pub(crate) fn new(name: &str) -> Self {
2423
let name: String = name.chars().take_while(|c| *c != '.').collect();
25-
let name = name.replace("-", "_");
24+
let name = name.replace('-', "_");
2625
Self {
2726
methods: Vec::with_capacity(0x100),
2827
name: name.into(),
2928
}
3029
}
31-
pub(crate) fn add_fn<'tcx>(&mut self, instance: Instance<'tcx>, tcx: TyCtxt<'tcx>,name:&str) {
30+
pub(crate) fn add_fn<'tcx>(&mut self, instance: Instance<'tcx>, tcx: TyCtxt<'tcx>, name: &str) {
3231
// TODO: figure out: What should it be???
3332
let param_env = ParamEnv::empty();
3433

3534
let def_id = instance.def_id();
3635
let mir = tcx.optimized_mir(def_id);
3736
let blocks = &(*mir.basic_blocks);
3837
let sig = instance.ty(tcx, param_env).fn_sig(tcx);
39-
let mut clr_method = CLRMethod::new(FunctionSignature::from_poly_sig(sig).expect("Could not resolve the function signature"),name);
38+
let mut clr_method = CLRMethod::new(
39+
FunctionSignature::from_poly_sig(sig)
40+
.expect("Could not resolve the function signature"),
41+
name,
42+
);
4043
for block_data in blocks {
44+
clr_method.begin_bb();
4145
for statement in &block_data.statements {
42-
clr_method.add_statement(statement);
46+
clr_method.add_statement(statement, mir, &tcx);
4347
}
4448
match &block_data.terminator {
45-
Some(term) => clr_method.add_terminator(term),
49+
Some(term) => clr_method.add_terminator(term,mir,&tcx),
4650
None => (),
4751
}
4852
}
49-
// Optimization is currently broken, and may produce invalid IR.
53+
// Optimization is currently broken, and may produce invalid IR.
5054
//clr_method.opt();
51-
clr_method.typecheck();
55+
//clr_method.typecheck();
56+
clr_method.add_locals(&mir.local_decls);
5257
println!("clr_method:{clr_method:?}");
5358
println!("instance:{instance:?}\n");
5459
self.methods.push(clr_method);
@@ -57,7 +62,9 @@ impl Assembly {
5762
println!("adding item:{}", item.symbol_name(tcx));
5863

5964
match item {
60-
MonoItem::Fn(instance) => self.add_fn(instance, tcx,&format!("{}",item.symbol_name(tcx))),
65+
MonoItem::Fn(instance) => {
66+
self.add_fn(instance, tcx, &format!("{}", item.symbol_name(tcx)))
67+
}
6168
_ => todo!("Unsupported item:\"{item:?}\"!"),
6269
}
6370
}

src/base_ir.rs

+43-32
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,58 @@
1-
use crate::{IString,VariableType,CLRMethod};
1+
use crate::IString;
2+
// An IR close, but not exactly equivalent to the CoreCLR IR.
3+
#[derive(Debug,Clone)]
4+
struct BranchInfo{bb_target:u16,value:u128}
25
#[derive(Debug, Clone)]
36
pub(crate) enum BaseIR {
7+
LDConstI8(i8),
48
LDConstI32(i32),
59
STArg(u32),
610
LDArg(u32),
711
STLoc(u32),
812
LDLoc(u32),
913
Add,
14+
Sub,
1015
Mul,
16+
Rem,
1117
Shl,
18+
Shr,
19+
Eq,
1220
Return,
21+
ConvF32,
22+
ConvI32,
23+
ConvI32Checked,
24+
ConvI8,
25+
//Not a real instruction, but a marker for a basic block.
26+
BBLabel{bb_id:u32},
27+
BEq{target:u32},
28+
GoTo{target:u32},
1329
}
14-
impl BaseIR{
15-
pub(crate) fn stack_change(&self)->i8{
16-
match self{
17-
Self::Add | Self::Mul | Self::Shl=>-1,
18-
Self::Return=>-1,
19-
Self::LDLoc(_)=>1,
20-
Self::LDArg(_)=>1,
21-
Self::STLoc(_)=>-1,
22-
Self::STArg(_)=>-1,
23-
Self::LDConstI32(_)=>-1,
30+
impl BaseIR {
31+
pub(crate) fn clr_ir(&self) -> IString {
32+
match self {
33+
Self::BBLabel{bb_id} => format!("\tBB_{bb_id}:\n"),
34+
Self::BEq{target} => format!("\tbeq BB_{target}\n"),
35+
Self::GoTo{target} => format!("\tbr BB_{target}\n"),
36+
Self::LDArg(arg) => format!("\tldarg.{arg}\n"),
37+
Self::STArg(arg) => format!("\tstarg.{arg}\n"),
38+
Self::LDLoc(arg) => format!("\tldloc.{arg}\n"),
39+
Self::STLoc(arg) => format!("\tstloc.{arg}\n"),
40+
Self::Return => "\tret\n".into(),
41+
Self::Add => "\tadd\n".into(),
42+
Self::Sub => "\tadd\n".into(),
43+
Self::Mul => "\tmul\n".into(),
44+
Self::Rem => "\trem\n".into(),
45+
Self::Shl => "\tshl\n".into(),
46+
Self::Shr => "\tshr\n".into(),
47+
Self::Eq => "\tceq\n".into(),
48+
Self::LDConstI8(i8const) => format!("\tldc.i4.s {i8const}\t\n"),
49+
Self::LDConstI32(i32const) => format!("\tldc.i4 {i32const}\t\n"),
50+
Self::ConvF32 => "\tconv.r4\n".into(),
51+
Self::ConvI8 => "\tconv.i1\n".into(),
52+
Self::ConvI32 => "\tconv.i4\n".into(),
53+
Self::ConvI32Checked => "\tconv.ovf.i4\n".into(),
54+
//_=>format!("\t//Comment!\n"),
2455
}
25-
}
26-
pub(crate) fn get_trivial_type(&self,parent_method:&CLRMethod)->Option<VariableType>{
27-
match self{
28-
Self::LDConstI32(_)=>Some(VariableType::I32),
29-
Self::LDLoc(var_id)=>parent_method.local_type(*var_id).cloned(),
30-
Self::LDArg(arg_id)=>Some(parent_method.get_arg_type(*arg_id).clone()),
31-
_=>None,
32-
}
33-
}
34-
pub(crate) fn clr_ir(&self)->IString{
35-
match self{
36-
Self::LDArg(arg)=>format!("\tldarg.{arg}\n"),
37-
Self::LDLoc(arg)=>format!("\tldloc.{arg}\n"),
38-
Self::STLoc(arg)=>format!("\tstloc.{arg}\n"),
39-
Self::Return=>"\tret\n".into(),
40-
Self::Add=>"\tadd\n".into(),
41-
Self::Mul=>"\tmul\n".into(),
42-
Self::Shl=>"\tshl\n".into(),
43-
Self::LDConstI32(i32const)=>format!("\tldc.i4 {i32const}\t\n"),
44-
_=>format!("\t//Comment!\n"),
45-
}.into()
56+
.into()
4657
}
4758
}

0 commit comments

Comments
 (0)