diff --git a/Cargo.lock b/Cargo.lock index 2e1df0c..f417853 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,18 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -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", -] +version = 4 [[package]] name = "allocator-api2" @@ -93,6 +81,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "2.6.0" @@ -172,6 +166,15 @@ dependencies = [ "strsim", ] +[[package]] +name = "clap_complete" +version = "4.5.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2348487adcd4631696ced64ccdb40d38ac4d31cae7f2eec8817fcea1b9d1c43c" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.5.18" @@ -300,20 +303,22 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fayalite" version = "0.3.0" -source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#bd75fdfefd642f6dd2210cfb003fa63f9dce114e" +source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#edcc5927a5f9ebca6df5720bb1f5931e50095a57" dependencies = [ + "base64", "bitvec", "blake3", "clap", + "clap_complete", "ctor", "eyre", "fayalite-proc-macros", "fayalite-visit-gen", - "hashbrown", + "hashbrown 0.15.5", "jobslot", "num-bigint", "num-traits", - "os_pipe", + "ordered-float", "petgraph", "serde", "serde_json", @@ -325,7 +330,7 @@ dependencies = [ [[package]] name = "fayalite-proc-macros" version = "0.3.0" -source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#bd75fdfefd642f6dd2210cfb003fa63f9dce114e" +source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#edcc5927a5f9ebca6df5720bb1f5931e50095a57" dependencies = [ "fayalite-proc-macros-impl", ] @@ -333,7 +338,7 @@ dependencies = [ [[package]] name = "fayalite-proc-macros-impl" version = "0.3.0" -source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#bd75fdfefd642f6dd2210cfb003fa63f9dce114e" +source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#edcc5927a5f9ebca6df5720bb1f5931e50095a57" dependencies = [ "base16ct", "num-bigint", @@ -348,7 +353,7 @@ dependencies = [ [[package]] name = "fayalite-visit-gen" version = "0.3.0" -source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#bd75fdfefd642f6dd2210cfb003fa63f9dce114e" +source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#edcc5927a5f9ebca6df5720bb1f5931e50095a57" dependencies = [ "indexmap", "prettyplease", @@ -366,6 +371,12 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "funty" version = "2.0.0" @@ -384,13 +395,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "wasi", + "r-efi", + "wasip2", ] [[package]] @@ -398,9 +410,16 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "ahash", "allocator-api2", + "equivalent", + "foldhash", ] [[package]] @@ -431,7 +450,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.5", "serde", ] @@ -449,16 +468,16 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobslot" -version = "0.2.19" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe10868679d7a24c2c67d862d0e64a342ce9aef7cdde9ce8019bd35d353d458d" +checksum = "58715c67c327da7f1558708348d68c207fd54900c4ae0529e29305d04d795b8c" dependencies = [ "cfg-if", "derive_destructure2", "getrandom", "libc", "scopeguard", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -514,22 +533,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] -name = "os_pipe" -version = "1.2.1" +name = "ordered-float" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" +checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" dependencies = [ - "libc", - "windows-sys 0.59.0", + "num-traits", + "rand", + "serde", ] [[package]] name = "petgraph" -version = "0.6.5" -source = "git+https://github.com/programmerjake/petgraph.git?rev=258ea8071209a924b73fe96f9f87a3b7b45cbc9f#258ea8071209a924b73fe96f9f87a3b7b45cbc9f" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ "fixedbitset", + "hashbrown 0.15.5", "indexmap", + "serde", ] [[package]] @@ -560,12 +583,37 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "radium" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", + "serde", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "serde", +] + [[package]] name = "rustix" version = "0.38.37" @@ -728,10 +776,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] [[package]] name = "which" @@ -745,6 +796,12 @@ dependencies = [ "winsafe", ] +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-sys" version = "0.52.0" @@ -763,6 +820,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -833,6 +899,12 @@ version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + [[package]] name = "wyz" version = "0.5.1" @@ -841,23 +913,3 @@ checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" dependencies = [ "tap", ] - -[[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", -] diff --git a/crates/cpu/src/instruction.rs b/crates/cpu/src/instruction.rs index dad8087..c410b56 100644 --- a/crates/cpu/src/instruction.rs +++ b/crates/cpu/src/instruction.rs @@ -5,6 +5,7 @@ use fayalite::{ expr::ops::{ArrayLiteral, ExprPartialEq}, intern::Interned, prelude::*, + sim::value::SimValuePartialEq, }; use std::{fmt, marker::PhantomData, ops::Range}; @@ -181,6 +182,12 @@ impl ExprPartialEq for OutputIntegerMode { } } +impl SimValuePartialEq for OutputIntegerMode { + fn sim_value_eq(this: &SimValue, other: &SimValue) -> bool { + SimValue::opaque(this) == SimValue::opaque(other) + } +} + pub const MOP_IMM_WIDTH: usize = 34; pub const MOP_MIN_REG_WIDTH: usize = 8; pub const COMMON_MOP_SRC_LEN: usize = 3; diff --git a/crates/cpu/src/reg_alloc/unit_free_regs_tracker.rs b/crates/cpu/src/reg_alloc/unit_free_regs_tracker.rs index d19cf2a..a7bf687 100644 --- a/crates/cpu/src/reg_alloc/unit_free_regs_tracker.rs +++ b/crates/cpu/src/reg_alloc/unit_free_regs_tracker.rs @@ -120,10 +120,7 @@ pub fn unit_free_regs_tracker( #[cfg(test)] mod tests { use super::*; - use fayalite::{ - cli::FormalMode, firrtl::ExportOptions, - module::transform::simplify_enums::SimplifyEnumsKind, testing::assert_formal, - }; + use fayalite::{firrtl::ExportOptions, module::transform::simplify_enums::SimplifyEnumsKind}; use std::num::NonZero; fn test_unit_free_regs_tracker( diff --git a/crates/cpu/src/util/array_vec.rs b/crates/cpu/src/util/array_vec.rs index 761f53f..4af5663 100644 --- a/crates/cpu/src/util/array_vec.rs +++ b/crates/cpu/src/util/array_vec.rs @@ -1,147 +1,10 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information -use fayalite::{ - expr::ops::{ExprCastTo, ExprIndex, ExprPartialEq, ExprPartialOrd}, - int::SizeType, - intern::{Intern, Interned}, - prelude::*, - ty::{MatchVariantWithoutScope, StaticType, TypeProperties}, -}; -use std::{marker::PhantomData, ops::Index}; +use fayalite::{expr::ops::ExprIndex, int::UIntInRangeInclusiveType, prelude::*}; -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct Length { - ty: UInt, - _phantom: PhantomData, -} - -impl Length { - pub fn new(max: Max::SizeType) -> Self { - Self { - ty: UInt::range_inclusive(0..=Max::as_usize(max)), - _phantom: PhantomData, - } - } - pub fn ty(self) -> UInt { - self.ty - } - pub fn zero(self) -> Expr { - Self::from_uint_unchecked(self.ty.zero()) - } - pub fn from_uint_unchecked(v: impl ToExpr) -> Expr { - Expr::from_canonical(Expr::canonical(v.to_expr())) - } - pub fn cast_from_uint_unchecked( - self, - v: impl ToExpr>, - ) -> Expr { - Self::from_uint_unchecked(v.to_expr().cast_to(self.ty)) - } - pub fn as_uint(this: impl ToExpr) -> Expr { - let this = this.to_expr(); - this.cast_to(Expr::ty(this).ty) - } -} - -impl ExprCastTo> for Length { - fn cast_to(src: Expr, to_type: UIntType) -> Expr> { - Expr::::from_canonical(Expr::canonical(src)).cast_to(to_type) - } -} - -#[allow(non_upper_case_globals)] -pub const Length: __LengthWithoutGenerics = __LengthWithoutGenerics {}; - -#[non_exhaustive] -pub struct __LengthWithoutGenerics {} - -impl Index for __LengthWithoutGenerics { - type Output = Length; - - fn index(&self, max: M) -> &Self::Output { - Interned::into_inner(Length::new(max).intern_sized()) - } -} - -impl Type for Length { - type BaseType = UInt; - type MaskType = Bool; - type MatchVariant = Expr; - type MatchActiveScope = (); - type MatchVariantAndInactiveScope = MatchVariantWithoutScope; - type MatchVariantsIter = std::iter::Once; - fn match_variants( - this: Expr, - source_location: SourceLocation, - ) -> Self::MatchVariantsIter { - let _ = source_location; - std::iter::once(MatchVariantWithoutScope(this)) - } - - fn mask_type(&self) -> Self::MaskType { - Bool - } - - fn canonical(&self) -> CanonicalType { - self.ty.canonical() - } - - fn from_canonical(canonical_type: CanonicalType) -> Self { - let ty = ::from_canonical(canonical_type); - if let Some(known_max) = Max::KNOWN_VALUE { - assert_eq!(ty, UInt::range_inclusive(0..=known_max)); - } - Self { - ty, - _phantom: PhantomData, - } - } - - fn source_location() -> SourceLocation { - SourceLocation::caller() - } -} - -impl StaticType for Length { - const TYPE: Self = Self { - ty: UInt { - width: Max::VALUE.next_power_of_two().ilog2() as usize, - }, - _phantom: PhantomData, - }; - const MASK_TYPE: Self::MaskType = Bool; - const TYPE_PROPERTIES: TypeProperties = { - let mut p = >::TYPE_PROPERTIES; - p.bit_width = Self::TYPE.ty.width; - p - }; - const MASK_TYPE_PROPERTIES: TypeProperties = Bool::TYPE_PROPERTIES; -} - -impl ExprPartialEq for Length { - fn cmp_eq(lhs: Expr, rhs: Expr) -> Expr { - Self::as_uint(lhs).cmp_eq(Self::as_uint(rhs)) - } - fn cmp_ne(lhs: Expr, rhs: Expr) -> Expr { - Self::as_uint(lhs).cmp_ne(Self::as_uint(rhs)) - } -} - -impl ExprPartialOrd for Length { - fn cmp_lt(lhs: Expr, rhs: Expr) -> Expr { - Self::as_uint(lhs).cmp_lt(Self::as_uint(rhs)) - } - fn cmp_le(lhs: Expr, rhs: Expr) -> Expr { - Self::as_uint(lhs).cmp_le(Self::as_uint(rhs)) - } - fn cmp_gt(lhs: Expr, rhs: Expr) -> Expr { - Self::as_uint(lhs).cmp_gt(Self::as_uint(rhs)) - } - fn cmp_ge(lhs: Expr, rhs: Expr) -> Expr { - Self::as_uint(lhs).cmp_ge(Self::as_uint(rhs)) - } -} +#[hdl] +pub type Length = UIntInRangeInclusiveType, Max>; /// like [`std::vec::Vec`], except with a [`Expr`] for [`len()`][`Self::len()`] and a fixed capacity #[hdl] @@ -156,7 +19,7 @@ impl ArrayVec { #[hdl] ArrayVec { elements: self.elements.uninit(), - len: self.len.zero(), + len: 0u8.cast_to(self.len), } } pub fn element(self) -> T { @@ -176,7 +39,7 @@ impl ArrayVec { let elements = elements.to_expr(); let len = len.to_expr(); assert_eq!( - Length::new(N::from_usize(Expr::ty(elements).len())), + Length[N::from_usize(Expr::ty(elements).len())], Expr::ty(len), "len type mismatch", ); @@ -191,7 +54,7 @@ impl ArrayVec { } pub fn is_empty(this: impl ToExpr) -> Expr { let len = Self::len(this); - len.cmp_eq(Expr::ty(len).zero()) + len.cmp_eq(0u8) } pub fn capacity(self) -> usize { self.elements.len() @@ -207,7 +70,7 @@ impl ArrayVec { let this = this.to_expr(); for (index, element) in this.elements.into_iter().enumerate() { #[hdl] - if index.cmp_lt(Length::as_uint(this.len)) { + if index.cmp_lt(this.len) { f(index, element); } } diff --git a/crates/cpu/tests/expected/reg_alloc.vcd b/crates/cpu/tests/expected/reg_alloc.vcd index ee343b4..f69c9a7 100644 --- a/crates/cpu/tests/expected/reg_alloc.vcd +++ b/crates/cpu/tests/expected/reg_alloc.vcd @@ -16832,38 +16832,6 @@ $upscope $end $upscope $end $enddefinitions $end $dumpvars -0vg -0wg -0xg -0yg -0zg -0{g -0|g -0}g -0~g -0!h -0"h -0#h -0$h -0%h -0&h -0'h -0(h -0)h -0*h -0+h -0,h -0-h -0.h -0/h -00h -01h -02h -03h -04h -05h -06h -07h b0 (_ b0 ia b0 )_ @@ -17370,6 +17338,26 @@ b0 ga b0 Jd b0 ha b0 Kd +b0 Ld +b0 Nd +b0 Md +b0 Od +0Pd +0Qd +0Rd +0Sd +0Td +0Ud +0Vd +0Wd +0Xd +0Yd +0Zd +0[d +0\d +0]d +0^d +0_d 0`d 0ad 0bd @@ -17386,438 +17374,6 @@ b0 Kd 0md 0nd 0od -b0 8h -0Hh -0Xh -0hh -0xh -0*i -0:i -0Ji -0Zi -b0 9h -0Ih -0Yh -0ih -0yh -0+i -0;i -0Ki -0[i -b0 :h -0Jh -0Zh -0jh -0zh -0,i -0i -0Ni -0^i -b0 =h -0Mh -0]h -0mh -0}h -0/i -0?i -0Oi -0_i -b0 >h -0Nh -0^h -0nh -0~h -00i -0@i -0Pi -0`i -b0 ?h -0Oh -0_h -0oh -0!i -01i -0Ai -0Qi -0ai -b0 @h -0Ph -0`h -0ph -0"i -02i -0Bi -0Ri -0bi -b0 Ah -0Qh -0ah -0qh -0#i -03i -0Ci -0Si -0ci -b0 Bh -0Rh -0bh -0rh -0$i -04i -0Di -0Ti -0di -b0 Ch -0Sh -0ch -0sh -0%i -05i -0Ei -0Ui -0ei -b0 Dh -0Th -0dh -0th -0&i -06i -0Fi -0Vi -0fi -b0 Eh -0Uh -0eh -0uh -0'i -07i -0Gi -0Wi -0gi -b0 Fh -0Vh -0fh -0vh -0(i -08i -0Hi -0Xi -0hi -b0 Gh -0Wh -0gh -0wh -0)i -09i -0Ii -0Yi -0ii -b0 Df -0Tf -0df -0tf -0&g -06g -0Fg -0Vg -0fg -b0 Ef -0Uf -0ef -0uf -0'g -07g -0Gg -0Wg -0gg -b0 Ff -0Vf -0ff -0vf -0(g -08g -0Hg -0Xg -0hg -b0 Gf -0Wf -0gf -0wf -0)g -09g -0Ig -0Yg -0ig -b0 Hf -0Xf -0hf -0xf -0*g -0:g -0Jg -0Zg -0jg -b0 If -0Yf -0if -0yf -0+g -0;g -0Kg -0[g -0kg -b0 Jf -0Zf -0jf -0zf -0,g -0g -0Ng -0^g -0ng -b0 Mf -0]f -0mf -0}f -0/g -0?g -0Og -0_g -0og -b0 Nf -0^f -0nf -0~f -00g -0@g -0Pg -0`g -0pg -b0 Of -0_f -0of -0!g -01g -0Ag -0Qg -0ag -0qg -b0 Pf -0`f -0pf -0"g -02g -0Bg -0Rg -0bg -0rg -b0 Qf -0af -0qf -0#g -03g -0Cg -0Sg -0cg -0sg -b0 Rf -0bf -0rf -0$g -04g -0Dg -0Tg -0dg -0tg -b0 Sf -0cf -0sf -0%g -05g -0Eg -0Ug -0eg -0ug -b0 ji -0zi -0,j -0j -0Nj -0^j -0nj -0~j -00k -b0 mi -0}i -0/j -0?j -0Oj -0_j -0oj -0!k -01k -b0 ni -0~i -00j -0@j -0Pj -0`j -0pj -0"k -02k -b0 oi -0!j -01j -0Aj -0Qj -0aj -0qj -0#k -03k -b0 pi -0"j -02j -0Bj -0Rj -0bj -0rj -0$k -04k -b0 qi -0#j -03j -0Cj -0Sj -0cj -0sj -0%k -05k -b0 ri -0$j -04j -0Dj -0Tj -0dj -0tj -0&k -06k -b0 si -0%j -05j -0Ej -0Uj -0ej -0uj -0'k -07k -b0 ti -0&j -06j -0Fj -0Vj -0fj -0vj -0(k -08k -b0 ui -0'j -07j -0Gj -0Wj -0gj -0wj -0)k -09k -b0 vi -0(j -08j -0Hj -0Xj -0hj -0xj -0*k -0:k -b0 wi -0)j -09j -0Ij -0Yj -0ij -0yj -0+k -0;k -b0 xi -0*j -0:j -0Jj -0Zj -0jj -0zj -0,k -0g +0Ng +0^g +0ng +b0 Mf +0]f +0mf +0}f +0/g +0?g +0Og +0_g +0og +b0 Nf +0^f +0nf +0~f +00g +0@g +0Pg +0`g +0pg +b0 Of +0_f +0of +0!g +01g +0Ag +0Qg +0ag +0qg +b0 Pf +0`f +0pf +0"g +02g +0Bg +0Rg +0bg +0rg +b0 Qf +0af +0qf +0#g +03g +0Cg +0Sg +0cg +0sg +b0 Rf +0bf +0rf +0$g +04g +0Dg +0Tg +0dg +0tg +b0 Sf +0cf +0sf +0%g +05g +0Eg +0Ug +0eg +0ug +0vg +0wg +0xg +0yg +0zg +0{g +0|g +0}g +0~g +0!h +0"h +0#h +0$h +0%h +0&h +0'h +0(h +0)h +0*h +0+h +0,h +0-h +0.h +0/h +00h +01h +02h +03h +04h +05h +06h +07h +b0 8h +0Hh +0Xh +0hh +0xh +0*i +0:i +0Ji +0Zi +b0 9h +0Ih +0Yh +0ih +0yh +0+i +0;i +0Ki +0[i +b0 :h +0Jh +0Zh +0jh +0zh +0,i +0i +0Ni +0^i +b0 =h +0Mh +0]h +0mh +0}h +0/i +0?i +0Oi +0_i +b0 >h +0Nh +0^h +0nh +0~h +00i +0@i +0Pi +0`i +b0 ?h +0Oh +0_h +0oh +0!i +01i +0Ai +0Qi +0ai +b0 @h +0Ph +0`h +0ph +0"i +02i +0Bi +0Ri +0bi +b0 Ah +0Qh +0ah +0qh +0#i +03i +0Ci +0Si +0ci +b0 Bh +0Rh +0bh +0rh +0$i +04i +0Di +0Ti +0di +b0 Ch +0Sh +0ch +0sh +0%i +05i +0Ei +0Ui +0ei +b0 Dh +0Th +0dh +0th +0&i +06i +0Fi +0Vi +0fi +b0 Eh +0Uh +0eh +0uh +0'i +07i +0Gi +0Wi +0gi +b0 Fh +0Vh +0fh +0vh +0(i +08i +0Hi +0Xi +0hi +b0 Gh +0Wh +0gh +0wh +0)i +09i +0Ii +0Yi +0ii +b0 ji +0zi +0,j +0j +0Nj +0^j +0nj +0~j +00k +b0 mi +0}i +0/j +0?j +0Oj +0_j +0oj +0!k +01k +b0 ni +0~i +00j +0@j +0Pj +0`j +0pj +0"k +02k +b0 oi +0!j +01j +0Aj +0Qj +0aj +0qj +0#k +03k +b0 pi +0"j +02j +0Bj +0Rj +0bj +0rj +0$k +04k +b0 qi +0#j +03j +0Cj +0Sj +0cj +0sj +0%k +05k +b0 ri +0$j +04j +0Dj +0Tj +0dj +0tj +0&k +06k +b0 si +0%j +05j +0Ej +0Uj +0ej +0uj +0'k +07k +b0 ti +0&j +06j +0Fj +0Vj +0fj +0vj +0(k +08k +b0 ui +0'j +07j +0Gj +0Wj +0gj +0wj +0)k +09k +b0 vi +0(j +08j +0Hj +0Xj +0hj +0xj +0*k +0:k +b0 wi +0)j +09j +0Ij +0Yj +0ij +0yj +0+k +0;k +b0 xi +0*j +0:j +0Jj +0Zj +0jj +0zj +0,k +0