forked from AbleOS/holey-bytes
adding packed structs
This commit is contained in:
parent
338e3f1519
commit
602249a48a
91
Cargo.lock
generated
91
Cargo.lock
generated
|
@ -2,6 +2,18 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.8.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"version_check",
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.1.3"
|
version = "1.1.3"
|
||||||
|
@ -60,6 +72,12 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colorchoice"
|
name = "colorchoice"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
@ -94,6 +112,9 @@ name = "hashbrown"
|
||||||
version = "0.14.5"
|
version = "0.14.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hbbytecode"
|
name = "hbbytecode"
|
||||||
|
@ -167,10 +188,35 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.86"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regalloc2"
|
name = "regalloc2"
|
||||||
version = "0.10.2"
|
version = "0.10.2"
|
||||||
source = "git+https://github.com/jakubDoka/regalloc2?branch=reuse-allocations#c1c7614b3a06d38113feaac11b4e4c9ab9e8f0c8"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"log",
|
"log",
|
||||||
|
@ -226,12 +272,35 @@ version = "1.13.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.77"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8parse"
|
name = "utf8parse"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
|
@ -308,3 +377,23 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xtask"
|
name = "xtask"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.7.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.7.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
|
@ -3,7 +3,6 @@ resolver = "2"
|
||||||
members = ["hbbytecode", "hbvm", "hbxrt", "xtask", "hblang", "hbjit"]
|
members = ["hbbytecode", "hbvm", "hbxrt", "xtask", "hblang", "hbjit"]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
strip = true
|
|
||||||
lto = true
|
lto = true
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
|
@ -10,7 +10,8 @@ path = "src/main.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
hbbytecode = { version = "0.1.0", path = "../hbbytecode" }
|
hbbytecode = { version = "0.1.0", path = "../hbbytecode" }
|
||||||
hbvm = { path = "../hbvm", features = ["nightly"] }
|
hbvm = { path = "../hbvm", features = ["nightly"] }
|
||||||
regalloc2 = { git = "https://github.com/jakubDoka/regalloc2", branch = "reuse-allocations", features = ["trace-log"] }
|
regalloc2 = "0.10.2"
|
||||||
|
#regalloc2 = { path = "../../regalloc2/" }#git = "https://github.com/jakubDoka/regalloc2", branch = "reuse-allocations", features = [] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
env_logger = "0.11.5"
|
env_logger = "0.11.5"
|
||||||
|
|
222
hblang/README.md
222
hblang/README.md
|
@ -162,6 +162,10 @@ Ty2 := struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
main := fn(): int {
|
main := fn(): int {
|
||||||
|
if @sizeof(packed struct {a: u8, b: u16}) != 3 {
|
||||||
|
return 9001
|
||||||
|
}
|
||||||
|
|
||||||
finst := Ty2.{ty: Ty.{a: 4, b: 1}, c: 3}
|
finst := Ty2.{ty: Ty.{a: 4, b: 1}, c: 3}
|
||||||
inst := odher_pass(finst)
|
inst := odher_pass(finst)
|
||||||
if inst.c == 3 {
|
if inst.c == 3 {
|
||||||
|
@ -505,11 +509,223 @@ main := fn(): int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//width += 1
|
width += 1
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if width < y break
|
if x < height {
|
||||||
y += 1
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width += 1
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width += 1
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width += 1
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width += 1
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width += 1
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width += 1
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width += 1
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width += 1
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width += 1
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width += 1
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width += 1
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if x < height {
|
||||||
|
//t += set_pixel(x, y, height)
|
||||||
|
x += 1
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
if set_pixel(x, y, height) != i return 0
|
||||||
|
if y == width break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return i
|
return i
|
||||||
|
|
|
@ -719,13 +719,17 @@ impl Codegen {
|
||||||
self.expr_ctx(expr, Ctx::default())
|
self.expr_ctx(expr, Ctx::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_struct(&mut self, fields: &[CommentOr<StructField>]) -> ty::Struct {
|
fn build_struct(
|
||||||
|
&mut self,
|
||||||
|
explicit_alignment: Option<u32>,
|
||||||
|
fields: &[CommentOr<StructField>],
|
||||||
|
) -> ty::Struct {
|
||||||
let fields = fields
|
let fields = fields
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(CommentOr::or)
|
.filter_map(CommentOr::or)
|
||||||
.map(|sf| Field { name: sf.name.into(), ty: self.ty(&sf.ty) })
|
.map(|sf| Field { name: sf.name.into(), ty: self.ty(&sf.ty) })
|
||||||
.collect();
|
.collect();
|
||||||
self.tys.structs.push(Struct { fields });
|
self.tys.structs.push(Struct { fields, explicit_alignment });
|
||||||
self.tys.structs.len() as u32 - 1
|
self.tys.structs.len() as u32 - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -733,9 +737,11 @@ impl Codegen {
|
||||||
use {Expr as E, TokenKind as T};
|
use {Expr as E, TokenKind as T};
|
||||||
let value = match *expr {
|
let value = match *expr {
|
||||||
E::Mod { id, .. } => Some(Value::ty(ty::Kind::Module(id).compress())),
|
E::Mod { id, .. } => Some(Value::ty(ty::Kind::Module(id).compress())),
|
||||||
E::Struct { fields, captured, .. } => {
|
E::Struct { fields, captured, packed, .. } => {
|
||||||
if captured.is_empty() {
|
if captured.is_empty() {
|
||||||
Some(Value::ty(ty::Kind::Struct(self.build_struct(fields)).compress()))
|
Some(Value::ty(
|
||||||
|
ty::Kind::Struct(self.build_struct(packed.then_some(1), fields)).compress(),
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
let values = captured
|
let values = captured
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -1940,7 +1946,12 @@ impl Codegen {
|
||||||
.unwrap_or_else(|| Loc::stack(self.ci.stack.allocate(self.tys.size_of(ty))));
|
.unwrap_or_else(|| Loc::stack(self.ci.stack.allocate(self.tys.size_of(ty))));
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
for &Field { ty, .. } in self.tys.structs[stuct as usize].fields.clone().iter() {
|
for &Field { ty, .. } in self.tys.structs[stuct as usize].fields.clone().iter() {
|
||||||
offset = Types::align_up(offset, self.tys.align_of(ty));
|
offset = Types::align_up(
|
||||||
|
offset,
|
||||||
|
self.tys.structs[stuct as usize]
|
||||||
|
.explicit_alignment
|
||||||
|
.unwrap_or(self.tys.align_of(ty)),
|
||||||
|
);
|
||||||
let size = self.tys.size_of(ty);
|
let size = self.tys.size_of(ty);
|
||||||
let ctx = Ctx::from(Value { ty, loc: loc.as_ref().offset(offset) });
|
let ctx = Ctx::from(Value { ty, loc: loc.as_ref().offset(offset) });
|
||||||
let left = left.as_ref().offset(offset);
|
let left = left.as_ref().offset(offset);
|
||||||
|
@ -2329,7 +2340,8 @@ impl Codegen {
|
||||||
match *trap {
|
match *trap {
|
||||||
trap::Trap::MakeStruct(trap::MakeStruct { file, struct_expr }) => {
|
trap::Trap::MakeStruct(trap::MakeStruct { file, struct_expr }) => {
|
||||||
let cfile = self.files[file as usize].clone();
|
let cfile = self.files[file as usize].clone();
|
||||||
let &Expr::Struct { fields, captured, .. } = struct_expr.get(&cfile).unwrap()
|
let &Expr::Struct { fields, captured, packed, .. } =
|
||||||
|
struct_expr.get(&cfile).unwrap()
|
||||||
else {
|
else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
@ -2350,7 +2362,8 @@ impl Codegen {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let stru = ty::Kind::Struct(self.build_struct(fields)).compress();
|
let stru =
|
||||||
|
ty::Kind::Struct(self.build_struct(packed.then_some(1), fields)).compress();
|
||||||
self.ci.vars.truncate(prev_len);
|
self.ci.vars.truncate(prev_len);
|
||||||
self.ct.vm.write_reg(1, stru.repr() as u64);
|
self.ct.vm.write_reg(1, stru.repr() as u64);
|
||||||
debug_assert_ne!(stru.expand().inner(), 1);
|
debug_assert_ne!(stru.expand().inner(), 1);
|
||||||
|
@ -2443,8 +2456,8 @@ impl Codegen {
|
||||||
Expr::BinOp {
|
Expr::BinOp {
|
||||||
left: &Expr::Ident { .. },
|
left: &Expr::Ident { .. },
|
||||||
op: TokenKind::Decl,
|
op: TokenKind::Decl,
|
||||||
right: Expr::Struct { fields, .. },
|
right: Expr::Struct { fields, packed, .. },
|
||||||
} => ty::Kind::Struct(self.build_struct(fields)),
|
} => ty::Kind::Struct(self.build_struct(packed.then_some(1), fields)),
|
||||||
Expr::BinOp { left, op: TokenKind::Decl, right } => {
|
Expr::BinOp { left, op: TokenKind::Decl, right } => {
|
||||||
let gid = self.tys.globals.len() as ty::Global;
|
let gid = self.tys.globals.len() as ty::Global;
|
||||||
self.tys.globals.push(Global { file, name: ident, ..Default::default() });
|
self.tys.globals.push(Global { file, name: ident, ..Default::default() });
|
||||||
|
|
|
@ -129,6 +129,7 @@ pub enum TokenKind {
|
||||||
Continue,
|
Continue,
|
||||||
Fn,
|
Fn,
|
||||||
Struct,
|
Struct,
|
||||||
|
Packed,
|
||||||
True,
|
True,
|
||||||
False,
|
False,
|
||||||
Idk,
|
Idk,
|
||||||
|
@ -314,6 +315,7 @@ gen_token_kind! {
|
||||||
Continue = b"continue",
|
Continue = b"continue",
|
||||||
Fn = b"fn",
|
Fn = b"fn",
|
||||||
Struct = b"struct",
|
Struct = b"struct",
|
||||||
|
Packed = b"packed",
|
||||||
True = b"true",
|
True = b"true",
|
||||||
False = b"false",
|
False = b"false",
|
||||||
Idk = b"idk",
|
Idk = b"idk",
|
||||||
|
|
|
@ -582,6 +582,7 @@ struct Field {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Struct {
|
struct Struct {
|
||||||
|
explicit_alignment: Option<u32>,
|
||||||
fields: Rc<[Field]>,
|
fields: Rc<[Field]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,7 +763,7 @@ impl Types {
|
||||||
let until = record.fields.iter().position(|f| f.name.as_ref() == field)?;
|
let until = record.fields.iter().position(|f| f.name.as_ref() == field)?;
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
for &Field { ty, .. } in &record.fields[..until] {
|
for &Field { ty, .. } in &record.fields[..until] {
|
||||||
offset = Self::align_up(offset, self.align_of(ty));
|
offset = Self::align_up(offset, record.explicit_alignment.unwrap_or(self.align_of(ty)));
|
||||||
offset += self.size_of(ty);
|
offset += self.size_of(ty);
|
||||||
}
|
}
|
||||||
Some((offset, record.fields[until].ty))
|
Some((offset, record.fields[until].ty))
|
||||||
|
@ -833,7 +834,7 @@ impl Types {
|
||||||
let mut offset = 0u32;
|
let mut offset = 0u32;
|
||||||
let record = &self.structs[stru as usize];
|
let record = &self.structs[stru as usize];
|
||||||
for &Field { ty, .. } in record.fields.iter() {
|
for &Field { ty, .. } in record.fields.iter() {
|
||||||
let align = self.align_of(ty);
|
let align = record.explicit_alignment.unwrap_or(self.align_of(ty));
|
||||||
offset = Self::align_up(offset, align);
|
offset = Self::align_up(offset, align);
|
||||||
offset += self.size_of(ty);
|
offset += self.size_of(ty);
|
||||||
}
|
}
|
||||||
|
@ -845,12 +846,16 @@ impl Types {
|
||||||
|
|
||||||
fn align_of(&self, ty: ty::Id) -> Size {
|
fn align_of(&self, ty: ty::Id) -> Size {
|
||||||
match ty.expand() {
|
match ty.expand() {
|
||||||
ty::Kind::Struct(stru) => self.structs[stru as usize]
|
ty::Kind::Struct(stru) => {
|
||||||
.fields
|
self.structs[stru as usize].explicit_alignment.unwrap_or_else(|| {
|
||||||
.iter()
|
self.structs[stru as usize]
|
||||||
.map(|&Field { ty, .. }| self.align_of(ty))
|
.fields
|
||||||
.max()
|
.iter()
|
||||||
.unwrap(),
|
.map(|&Field { ty, .. }| self.align_of(ty))
|
||||||
|
.max()
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
|
}
|
||||||
ty::Kind::Slice(arr) => {
|
ty::Kind::Slice(arr) => {
|
||||||
let arr = &self.arrays[arr as usize];
|
let arr = &self.arrays[arr as usize];
|
||||||
match arr.len {
|
match arr.len {
|
||||||
|
|
|
@ -64,6 +64,7 @@ pub struct Parser<'a, 'b> {
|
||||||
symbols: &'b mut Symbols,
|
symbols: &'b mut Symbols,
|
||||||
ns_bound: usize,
|
ns_bound: usize,
|
||||||
trailing_sep: bool,
|
trailing_sep: bool,
|
||||||
|
packed: bool,
|
||||||
idents: Vec<ScopeIdent>,
|
idents: Vec<ScopeIdent>,
|
||||||
captured: Vec<Ident>,
|
captured: Vec<Ident>,
|
||||||
}
|
}
|
||||||
|
@ -80,6 +81,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
symbols,
|
symbols,
|
||||||
ns_bound: 0,
|
ns_bound: 0,
|
||||||
trailing_sep: false,
|
trailing_sep: false,
|
||||||
|
packed: false,
|
||||||
idents: Vec::new(),
|
idents: Vec::new(),
|
||||||
captured: Vec::new(),
|
captured: Vec::new(),
|
||||||
}
|
}
|
||||||
|
@ -286,7 +288,20 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
T::False => E::Bool { pos, value: false },
|
T::False => E::Bool { pos, value: false },
|
||||||
T::Idk => E::Idk { pos },
|
T::Idk => E::Idk { pos },
|
||||||
T::DQuote => E::String { pos, literal: self.move_str(token) },
|
T::DQuote => E::String { pos, literal: self.move_str(token) },
|
||||||
|
T::Packed => {
|
||||||
|
self.packed = true;
|
||||||
|
let expr = self.unit_expr();
|
||||||
|
if self.packed {
|
||||||
|
self.report(
|
||||||
|
expr.pos(),
|
||||||
|
"this can not be packed \
|
||||||
|
(unlike your mom that gets packed every day by me)",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expr
|
||||||
|
}
|
||||||
T::Struct => E::Struct {
|
T::Struct => E::Struct {
|
||||||
|
packed: std::mem::take(&mut self.packed),
|
||||||
fields: {
|
fields: {
|
||||||
self.ns_bound = self.idents.len();
|
self.ns_bound = self.idents.len();
|
||||||
self.expect_advance(T::LBrace);
|
self.expect_advance(T::LBrace);
|
||||||
|
@ -746,6 +761,7 @@ generate_expr! {
|
||||||
fields: &'a [CommentOr<'a, StructField<'a>>],
|
fields: &'a [CommentOr<'a, StructField<'a>>],
|
||||||
captured: &'a [Ident],
|
captured: &'a [Ident],
|
||||||
trailing_comma: bool,
|
trailing_comma: bool,
|
||||||
|
packed: bool,
|
||||||
},
|
},
|
||||||
/// `[Expr] LIST('.{', ',', '}', Ident [':' Expr])`
|
/// `[Expr] LIST('.{', ',', '}', Ident [':' Expr])`
|
||||||
Ctor {
|
Ctor {
|
||||||
|
@ -1032,7 +1048,11 @@ impl<'a> fmt::Display for Expr<'a> {
|
||||||
write!(f, "@{name}(")?;
|
write!(f, "@{name}(")?;
|
||||||
fmt_list(f, false, ")", ",", args, fmt::Display::fmt)
|
fmt_list(f, false, ")", ",", args, fmt::Display::fmt)
|
||||||
}
|
}
|
||||||
Self::Struct { fields, trailing_comma, .. } => {
|
Self::Struct { fields, trailing_comma, packed, .. } => {
|
||||||
|
if packed {
|
||||||
|
write!(f, "packed ")?;
|
||||||
|
}
|
||||||
|
|
||||||
write!(f, "struct {{")?;
|
write!(f, "struct {{")?;
|
||||||
fmt_list_low(f, trailing_comma, "}", ",", fields, |field, f| {
|
fmt_list_low(f, trailing_comma, "}", ",", fields, |field, f| {
|
||||||
match field {
|
match field {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
ident::{self, Ident},
|
ident::{self, Ident},
|
||||||
instrs::{self},
|
instrs,
|
||||||
lexer::{self, TokenKind},
|
lexer::{self, TokenKind},
|
||||||
log,
|
log,
|
||||||
parser::{
|
parser::{
|
||||||
|
@ -12,7 +12,7 @@ use {
|
||||||
},
|
},
|
||||||
task,
|
task,
|
||||||
ty::{self},
|
ty::{self},
|
||||||
Field, Func, HashMap, Offset, Reloc, Sig, Size, Struct, SymKey, TypedReloc, Types,
|
Field, Func, Offset, Reloc, Sig, Size, Struct, SymKey, TypedReloc, Types,
|
||||||
},
|
},
|
||||||
core::fmt,
|
core::fmt,
|
||||||
regalloc2::VReg,
|
regalloc2::VReg,
|
||||||
|
@ -1251,13 +1251,17 @@ impl Codegen {
|
||||||
self.expr_ctx(expr, Ctx::default())
|
self.expr_ctx(expr, Ctx::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_struct(&mut self, fields: &[CommentOr<StructField>]) -> ty::Struct {
|
fn build_struct(
|
||||||
|
&mut self,
|
||||||
|
explicit_alignment: Option<u32>,
|
||||||
|
fields: &[CommentOr<StructField>],
|
||||||
|
) -> ty::Struct {
|
||||||
let fields = fields
|
let fields = fields
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(CommentOr::or)
|
.filter_map(CommentOr::or)
|
||||||
.map(|sf| Field { name: sf.name.into(), ty: self.ty(&sf.ty) })
|
.map(|sf| Field { name: sf.name.into(), ty: self.ty(&sf.ty) })
|
||||||
.collect();
|
.collect();
|
||||||
self.tys.structs.push(Struct { fields });
|
self.tys.structs.push(Struct { fields, explicit_alignment });
|
||||||
self.tys.structs.len() as u32 - 1
|
self.tys.structs.len() as u32 - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1315,7 +1319,7 @@ impl Codegen {
|
||||||
let inps = [VOID, lhs, rhs];
|
let inps = [VOID, lhs, rhs];
|
||||||
Some(self.ci.nodes.new_node(ty::bin_ret(ty, op), Kind::BinOp { op }, inps))
|
Some(self.ci.nodes.new_node(ty::bin_ret(ty, op), Kind::BinOp { op }, inps))
|
||||||
}
|
}
|
||||||
Expr::UnOp { pos, op: TokenKind::Band, val } => {
|
Expr::UnOp { pos: _, op: TokenKind::Band, val: _ } => {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
Expr::UnOp { pos, op, val } => {
|
Expr::UnOp { pos, op, val } => {
|
||||||
|
@ -1466,6 +1470,11 @@ impl Codegen {
|
||||||
self.ci.nodes.modify_input(scope_var.value, 2, loop_var.value);
|
self.ci.nodes.modify_input(scope_var.value, 2, loop_var.value);
|
||||||
self.ci.nodes.lock(scope_var.value);
|
self.ci.nodes.lock(scope_var.value);
|
||||||
} else {
|
} else {
|
||||||
|
if dest_var.value == scope_var.value {
|
||||||
|
self.ci.nodes.unlock(dest_var.value);
|
||||||
|
dest_var.value = VOID;
|
||||||
|
self.ci.nodes.lock(dest_var.value);
|
||||||
|
}
|
||||||
let phi = &self.ci.nodes[scope_var.value];
|
let phi = &self.ci.nodes[scope_var.value];
|
||||||
debug_assert_eq!(phi.kind, Kind::Phi);
|
debug_assert_eq!(phi.kind, Kind::Phi);
|
||||||
debug_assert_eq!(phi.inputs[2], VOID);
|
debug_assert_eq!(phi.inputs[2], VOID);
|
||||||
|
@ -1482,6 +1491,11 @@ impl Codegen {
|
||||||
self.ci.nodes.lock(dest_var.value);
|
self.ci.nodes.lock(dest_var.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug_assert!(
|
||||||
|
self.ci.nodes[dest_var.value].kind != Kind::Phi
|
||||||
|
|| self.ci.nodes[dest_var.value].inputs[2] != 0
|
||||||
|
);
|
||||||
|
|
||||||
self.ci.nodes.unlock_remove(scope_var.value);
|
self.ci.nodes.unlock_remove(scope_var.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1748,7 +1762,7 @@ impl Codegen {
|
||||||
self.ci.emit(instrs::st(reg::RET_ADDR, reg::STACK_PTR, 0, 0));
|
self.ci.emit(instrs::st(reg::RET_ADDR, reg::STACK_PTR, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ci.nodes.basic_blocks();
|
//self.ci.nodes.basic_blocks();
|
||||||
//self.ci.nodes.graphviz();
|
//self.ci.nodes.graphviz();
|
||||||
|
|
||||||
self.ci.vars = orig_vars;
|
self.ci.vars = orig_vars;
|
||||||
|
@ -1799,15 +1813,14 @@ impl Codegen {
|
||||||
let mut nodes = std::mem::take(&mut self.ci.nodes);
|
let mut nodes = std::mem::take(&mut self.ci.nodes);
|
||||||
|
|
||||||
let func = Function::new(&mut nodes, &self.tys, sig);
|
let func = Function::new(&mut nodes, &self.tys, sig);
|
||||||
dbg!(&func);
|
|
||||||
let mut env = regalloc2::MachineEnv {
|
let mut env = regalloc2::MachineEnv {
|
||||||
preferred_regs_by_class: [
|
preferred_regs_by_class: [
|
||||||
(1..12).map(|i| regalloc2::PReg::new(i, regalloc2::RegClass::Int)).collect(),
|
(1..5).map(|i| regalloc2::PReg::new(i, regalloc2::RegClass::Int)).collect(),
|
||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
],
|
],
|
||||||
non_preferred_regs_by_class: [
|
non_preferred_regs_by_class: [
|
||||||
(12..64).map(|i| regalloc2::PReg::new(i, regalloc2::RegClass::Int)).collect(),
|
(12..16).map(|i| regalloc2::PReg::new(i, regalloc2::RegClass::Int)).collect(),
|
||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
],
|
],
|
||||||
|
@ -1817,131 +1830,131 @@ impl Codegen {
|
||||||
if self.ci.call_count != 0 {
|
if self.ci.call_count != 0 {
|
||||||
std::mem::swap(&mut env.preferred_regs_by_class, &mut env.non_preferred_regs_by_class);
|
std::mem::swap(&mut env.preferred_regs_by_class, &mut env.non_preferred_regs_by_class);
|
||||||
};
|
};
|
||||||
let options = regalloc2::RegallocOptions { verbose_log: false, validate_ssa: true };
|
let options = regalloc2::RegallocOptions { verbose_log: false, validate_ssa: false };
|
||||||
let iters = std::time::SystemTime::now()
|
let iters = std::hint::black_box(10000);
|
||||||
.duration_since(std::time::SystemTime::UNIX_EPOCH)
|
|
||||||
.unwrap()
|
//let mut ctx = regalloc2::Ctx::default();
|
||||||
.as_nanos() as u32
|
//regalloc2::run_with_ctx(&func, &env, &options, &mut ctx)
|
||||||
% 300
|
// .unwrap_or_else(|err| panic!("{err}"));
|
||||||
+ 300;
|
//let now = std::time::Instant::now();
|
||||||
let mut output =
|
//for _ in 0..iters {
|
||||||
regalloc2::run(&func, &env, &options).unwrap_or_else(|err| panic!("{err}"));
|
// regalloc2::run_with_ctx(&func, &env, &options, &mut ctx)
|
||||||
|
// .unwrap_or_else(|err| panic!("{err}"));
|
||||||
|
//}
|
||||||
|
//eprintln!("took: {:?}", now.elapsed().checked_div(iters).unwrap());
|
||||||
|
|
||||||
let now = std::time::Instant::now();
|
let now = std::time::Instant::now();
|
||||||
for i in 0..iters {
|
for _ in 0..iters {
|
||||||
output = regalloc2::run(&func, &env, &options).unwrap_or_else(|err| panic!("{err}"));
|
regalloc2::run(&func, &env, &options).unwrap_or_else(|err| panic!("{err}"));
|
||||||
if (iters + i) % 2 == 0 {
|
|
||||||
std::mem::swap(
|
|
||||||
&mut env.preferred_regs_by_class,
|
|
||||||
&mut env.non_preferred_regs_by_class,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
eprintln!("took: {:?}", now.elapsed().checked_div(iters).unwrap());
|
eprintln!("took: {:?}", now.elapsed().checked_div(iters).unwrap());
|
||||||
|
|
||||||
let mut saved_regs = HashMap::<u8, u8>::default();
|
0
|
||||||
let mut atr = |allc: regalloc2::Allocation| {
|
|
||||||
debug_assert!(allc.is_reg());
|
|
||||||
let hvenc = regalloc2::PReg::from_index(allc.index()).hw_enc() as u8;
|
|
||||||
if hvenc <= 12 {
|
|
||||||
return hvenc;
|
|
||||||
}
|
|
||||||
let would_insert = saved_regs.len() as u8 + reg::RET_ADDR + 1;
|
|
||||||
*saved_regs.entry(hvenc).or_insert(would_insert)
|
|
||||||
};
|
|
||||||
|
|
||||||
for (i, block) in func.blocks.iter().enumerate() {
|
//let mut saved_regs = HashMap::<u8, u8>::default();
|
||||||
let blk = regalloc2::Block(i as _);
|
//let mut atr = |allc: regalloc2::Allocation| {
|
||||||
func.nodes[block.nid].offset = self.ci.code.len() as _;
|
// debug_assert!(allc.is_reg());
|
||||||
for instr_or_edit in output.block_insts_and_edits(&func, blk) {
|
// let hvenc = regalloc2::PReg::from_index(allc.index()).hw_enc() as u8;
|
||||||
let inst = match instr_or_edit {
|
// if hvenc <= 12 {
|
||||||
regalloc2::InstOrEdit::Inst(inst) => inst,
|
// return hvenc;
|
||||||
regalloc2::InstOrEdit::Edit(®alloc2::Edit::Move { from, to }) => {
|
// }
|
||||||
self.ci.emit(instrs::cp(atr(to), atr(from)));
|
// let would_insert = saved_regs.len() as u8 + reg::RET_ADDR + 1;
|
||||||
continue;
|
// *saved_regs.entry(hvenc).or_insert(would_insert)
|
||||||
}
|
//};
|
||||||
};
|
|
||||||
|
|
||||||
let nid = func.instrs[inst.index()].nid;
|
//for (i, block) in func.blocks.iter().enumerate() {
|
||||||
if nid == NEVER {
|
// let blk = regalloc2::Block(i as _);
|
||||||
continue;
|
// func.nodes[block.nid].offset = self.ci.code.len() as _;
|
||||||
};
|
// for instr_or_edit in ctx.output.block_insts_and_edits(&func, blk) {
|
||||||
let allocs = output.inst_allocs(inst);
|
// let inst = match instr_or_edit {
|
||||||
let node = &func.nodes[nid];
|
// regalloc2::InstOrEdit::Inst(inst) => inst,
|
||||||
match node.kind {
|
// regalloc2::InstOrEdit::Edit(®alloc2::Edit::Move { from, to }) => {
|
||||||
Kind::If => {
|
// self.ci.emit(instrs::cp(atr(to), atr(from)));
|
||||||
let &[_, cond] = node.inputs.as_slice() else { unreachable!() };
|
// continue;
|
||||||
if let Kind::BinOp { op } = func.nodes[cond].kind
|
// }
|
||||||
&& let Some((op, swapped)) = op.cond_op(node.ty.is_signed())
|
// };
|
||||||
{
|
|
||||||
let rel = Reloc::new(self.ci.code.len(), 3, 2);
|
|
||||||
self.ci.jump_relocs.push((node.outputs[!swapped as usize], rel));
|
|
||||||
let &[lhs, rhs] = allocs else { unreachable!() };
|
|
||||||
self.ci.emit(op(atr(lhs), atr(rhs), 0));
|
|
||||||
} else {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Kind::Loop | Kind::Region => {
|
|
||||||
if node.ralloc_backref as usize != i + 1 {
|
|
||||||
let rel = Reloc::new(self.ci.code.len(), 1, 4);
|
|
||||||
self.ci.jump_relocs.push((nid, rel));
|
|
||||||
self.ci.emit(instrs::jmp(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Kind::Return => {
|
|
||||||
if i != func.blocks.len() - 1 {
|
|
||||||
let rel = Reloc::new(self.ci.code.len(), 1, 4);
|
|
||||||
self.ci.ret_relocs.push(rel);
|
|
||||||
self.ci.emit(instrs::jmp(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Kind::CInt { value } => {
|
|
||||||
self.ci.emit(instrs::li64(atr(allocs[0]), value as _));
|
|
||||||
}
|
|
||||||
Kind::UnOp { op } => {
|
|
||||||
let op = op.unop().expect("TODO: unary operator not supported");
|
|
||||||
let &[dst, oper] = allocs else { unreachable!() };
|
|
||||||
self.ci.emit(op(atr(dst), atr(oper)));
|
|
||||||
}
|
|
||||||
Kind::BinOp { op } => {
|
|
||||||
let &[.., rhs] = node.inputs.as_slice() else { unreachable!() };
|
|
||||||
|
|
||||||
if let Kind::CInt { value } = func.nodes[rhs].kind
|
// let nid = func.instrs[inst.index()].nid;
|
||||||
&& let Some(op) =
|
// if nid == NEVER {
|
||||||
op.imm_binop(node.ty.is_signed(), func.tys.size_of(node.ty))
|
// continue;
|
||||||
{
|
// };
|
||||||
let &[dst, lhs] = allocs else { unreachable!() };
|
// let allocs = ctx.output.inst_allocs(inst);
|
||||||
self.ci.emit(op(atr(dst), atr(lhs), value as _));
|
// let node = &func.nodes[nid];
|
||||||
} else if let Some(op) =
|
// match node.kind {
|
||||||
op.binop(node.ty.is_signed(), func.tys.size_of(node.ty))
|
// Kind::If => {
|
||||||
{
|
// let &[_, cond] = node.inputs.as_slice() else { unreachable!() };
|
||||||
let &[dst, lhs, rhs] = allocs else { unreachable!() };
|
// if let Kind::BinOp { op } = func.nodes[cond].kind
|
||||||
self.ci.emit(op(atr(dst), atr(lhs), atr(rhs)));
|
// && let Some((op, swapped)) = op.cond_op(node.ty.is_signed())
|
||||||
} else if op.cond_op(node.ty.is_signed()).is_some() {
|
// {
|
||||||
} else {
|
// let rel = Reloc::new(self.ci.code.len(), 3, 2);
|
||||||
todo!()
|
// self.ci.jump_relocs.push((node.outputs[!swapped as usize], rel));
|
||||||
}
|
// let &[lhs, rhs] = allocs else { unreachable!() };
|
||||||
}
|
// self.ci.emit(op(atr(lhs), atr(rhs), 0));
|
||||||
Kind::Call { func } => {
|
// } else {
|
||||||
self.ci.relocs.push(TypedReloc {
|
// todo!()
|
||||||
target: ty::Kind::Func(func).compress(),
|
// }
|
||||||
reloc: Reloc::new(self.ci.code.len(), 3, 4),
|
// }
|
||||||
});
|
// Kind::Loop | Kind::Region => {
|
||||||
self.ci.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
|
// if node.ralloc_backref as usize != i + 1 {
|
||||||
}
|
// let rel = Reloc::new(self.ci.code.len(), 1, 4);
|
||||||
Kind::Start | Kind::End | Kind::Phi | Kind::Arg { .. } | Kind::Ctrl { .. } => {
|
// self.ci.jump_relocs.push((nid, rel));
|
||||||
unreachable!()
|
// self.ci.emit(instrs::jmp(0));
|
||||||
}
|
// }
|
||||||
Kind::Stck { .. } => todo!(),
|
// }
|
||||||
Kind::Load { .. } => todo!(),
|
// Kind::Return => {
|
||||||
Kind::Stre { .. } => todo!(),
|
// if i != func.blocks.len() - 1 {
|
||||||
}
|
// let rel = Reloc::new(self.ci.code.len(), 1, 4);
|
||||||
}
|
// self.ci.ret_relocs.push(rel);
|
||||||
}
|
// self.ci.emit(instrs::jmp(0));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// Kind::CInt { value } => {
|
||||||
|
// self.ci.emit(instrs::li64(atr(allocs[0]), value as _));
|
||||||
|
// }
|
||||||
|
// Kind::UnOp { op } => {
|
||||||
|
// let op = op.unop().expect("TODO: unary operator not supported");
|
||||||
|
// let &[dst, oper] = allocs else { unreachable!() };
|
||||||
|
// self.ci.emit(op(atr(dst), atr(oper)));
|
||||||
|
// }
|
||||||
|
// Kind::BinOp { op } => {
|
||||||
|
// let &[.., rhs] = node.inputs.as_slice() else { unreachable!() };
|
||||||
|
|
||||||
self.ci.nodes = nodes;
|
// if let Kind::CInt { value } = func.nodes[rhs].kind
|
||||||
|
// && let Some(op) =
|
||||||
|
// op.imm_binop(node.ty.is_signed(), func.tys.size_of(node.ty))
|
||||||
|
// {
|
||||||
|
// let &[dst, lhs] = allocs else { unreachable!() };
|
||||||
|
// self.ci.emit(op(atr(dst), atr(lhs), value as _));
|
||||||
|
// } else if let Some(op) =
|
||||||
|
// op.binop(node.ty.is_signed(), func.tys.size_of(node.ty))
|
||||||
|
// {
|
||||||
|
// let &[dst, lhs, rhs] = allocs else { unreachable!() };
|
||||||
|
// self.ci.emit(op(atr(dst), atr(lhs), atr(rhs)));
|
||||||
|
// } else if op.cond_op(node.ty.is_signed()).is_some() {
|
||||||
|
// } else {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// Kind::Call { func } => {
|
||||||
|
// self.ci.relocs.push(TypedReloc {
|
||||||
|
// target: ty::Kind::Func(func).compress(),
|
||||||
|
// reloc: Reloc::new(self.ci.code.len(), 3, 4),
|
||||||
|
// });
|
||||||
|
// self.ci.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
|
||||||
|
// }
|
||||||
|
// Kind::Start | Kind::End | Kind::Phi | Kind::Arg { .. } | Kind::Ctrl { .. } => {
|
||||||
|
// unreachable!()
|
||||||
|
// }
|
||||||
|
// Kind::Stck { .. } => todo!(),
|
||||||
|
// Kind::Load { .. } => todo!(),
|
||||||
|
// Kind::Stre { .. } => todo!(),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
saved_regs.len()
|
//self.ci.nodes = nodes;
|
||||||
|
|
||||||
|
//saved_regs.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: sometimes its better to do this in bulk
|
// TODO: sometimes its better to do this in bulk
|
||||||
|
@ -2042,7 +2055,7 @@ impl Codegen {
|
||||||
left: &Expr::Ident { .. },
|
left: &Expr::Ident { .. },
|
||||||
op: TokenKind::Decl,
|
op: TokenKind::Decl,
|
||||||
right: Expr::Struct { fields, .. },
|
right: Expr::Struct { fields, .. },
|
||||||
} => ty::Kind::Struct(self.build_struct(fields)),
|
} => ty::Kind::Struct(self.build_struct(None, fields)),
|
||||||
Expr::BinOp { .. } => {
|
Expr::BinOp { .. } => {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue