From 3ca4bf5292ab22d5cd1b4d7aea9385a2771fdc52 Mon Sep 17 00:00:00 2001 From: Ferdia McKeogh Date: Mon, 1 Apr 2024 14:11:48 +0100 Subject: [PATCH] Working fibonacci! --- Earthfile | 1 + borealis/src/brig/codegen.rs | 26 +++- borealis/src/brig/mod.rs | 98 ++++++++++++- borealis/src/rudder/build.rs | 260 +++++++++++++++++++++++------------ borealis/src/rudder/mod.rs | 34 ++++- 5 files changed, 320 insertions(+), 99 deletions(-) diff --git a/Earthfile b/Earthfile index 42b9791..e0acfe0 100644 --- a/Earthfile +++ b/Earthfile @@ -102,6 +102,7 @@ e2e-test-brig: COPY (+e2e-test-sailrs/arm-v9.4-a.rkyv) arm-v9.4-a.rkyv COPY (+build-borealis/borealis) borealis + RUN mkdir target RUN ./borealis --standalone arm-v9.4-a.rkyv aarch64.rs RUN rustc --edition 2021 aarch64.rs # RUN ./aarch64 91500421 diff --git a/borealis/src/brig/codegen.rs b/borealis/src/brig/codegen.rs index 04d3114..22753d7 100644 --- a/borealis/src/brig/codegen.rs +++ b/borealis/src/brig/codegen.rs @@ -122,8 +122,9 @@ pub fn codegen(rudder: Context, entrypoint: InternedString) -> TokenStream { fn decode_execute(value: u32, state: &mut State, tracer: &mut T) -> ExecuteResult { // reset SEE + // todo: for the love of god make this not break if registers are regenerated unsafe { - *(state.data.as_mut_ptr().byte_offset(0x38f0) as *mut u64) = 0 + *(state.data.as_mut_ptr().byte_offset(0x3920) as *mut u64) = 0 }; #entrypoint @@ -199,9 +200,14 @@ pub fn codegen_type(typ: Rc) -> TokenStream { element_count, element_type, } => { - let count = quote!(#element_count); let element_type = codegen_type(element_type.clone()); - quote!([#element_type; #count]) + + if *element_count == 0 { + quote!(Vec<#element_type>) + } else { + let count = quote!(#element_count); + quote!([#element_type; #count]) + } } Type::Bundled { value, len } => { let value_type = codegen_type(value.clone()); @@ -456,6 +462,8 @@ fn codegen_stmt(stmt: Statement) -> TokenStream { quote! { ((#ident) != 0) } + } else if target.is_unknown_length_vector() { + quote!(Vec::from(#ident)) } else { match kind { CastOperationKind::ZeroExtend => { @@ -606,10 +614,16 @@ fn codegen_stmt(stmt: Statement) -> TokenStream { } } StatementKind::ReadElement { vector, index } => { + let index_typ = index.typ(); + let vector = get_ident(&vector); let index = get_ident(&index); - // todo remove this cast, need "machine word" size in rudder? - quote!(#vector[(#index) as usize]) + + if let Type::Bundled { .. } = &*index_typ { + quote!(#vector[(#index.value) as usize]) + } else { + quote!(#vector[(#index) as usize]) + } } StatementKind::MutateElement { vector, @@ -619,7 +633,7 @@ fn codegen_stmt(stmt: Statement) -> TokenStream { let vector = get_ident(&vector); let index = get_ident(&index); let value = get_ident(&value); - // todo remove this cast, need "machine word" size in rudder? + // todo: support bundle indexes quote! { { let mut local = #vector.clone(); diff --git a/borealis/src/brig/mod.rs b/borealis/src/brig/mod.rs index 85de905..badc83b 100644 --- a/borealis/src/brig/mod.rs +++ b/borealis/src/brig/mod.rs @@ -54,6 +54,48 @@ const FN_ALLOWLIST: &[&str] = &[ "__DecodeA64_BranchExcSys", "decode_b_cond_aarch64_instrs_branch_conditional_cond", "execute_aarch64_instrs_branch_conditional_cond", + "ConditionHolds", + "BranchNotTaken", + "HaveStatisticalProfiling", + "IsFeatureImplemented", + "num_of_Feature", + "decode_add_addsub_shift_aarch64_instrs_integer_arithmetic_add_sub_shiftedreg", + "decode_orr_log_shift_aarch64_instrs_integer_logical_shiftedreg", + "execute_aarch64_instrs_integer_logical_shiftedreg", + "decode_b_uncond_aarch64_instrs_branch_unconditional_immediate", + "execute_aarch64_instrs_branch_unconditional_immediate", + "PC_read", + "BranchTo", + "Hint_Branch", + "UsingAArch32", + "HaveAArch32", + "HaveAArch64", + "AArch64_BranchAddr", + "AddrTop", + "HaveEL", + "S1TranslationRegime", + "ELUsingAArch32", + "IsSecureBelowEL3", + "SCR_GEN_read", + "Mk_SCRType", + "_get_SCRType_NS", + "ELStateUsingAArch32", + "ELStateUsingAArch32K", + "HaveAArch32EL", + "HaveVirtHostExt", + "EffectiveTBI", + "_get_TCR_EL1_Type_TBI0", + "HavePACExt", + "HaveBRBExt", + "decode_svc_aarch64_instrs_system_exceptions_runtime_svc", + "execute_aarch64_instrs_system_exceptions_runtime_svc", + "AArch64_CheckForSVCTrap", + "HaveFGTExt", + "AArch64_CallSupervisor", + "SSAdvance", + "decode_hvc_aarch64_instrs_system_exceptions_runtime_hvc", + "DebugTarget", + "CurrentSecurityState", ]; mod codegen; @@ -155,15 +197,48 @@ pub fn sail_to_brig>( let mut state = State::default(); - text.chunks(4).map(|c| { - let mut buf = [0u8;4]; - buf.copy_from_slice(c); - u32::from_le_bytes(buf) - }).for_each(|insr| { + // set enabled features + unsafe { + *(state.data.as_mut_ptr().byte_offset(0x18ed0) as *mut [bool; 259]) = [ + false, false, false, false, true, true, true, false, false, true, true, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, + ] + }; + + + loop { + let pc = unsafe { (state.data.as_mut_ptr().byte_offset(12704) as *mut u64) }; + let insr = unsafe { *(text.as_ptr().offset(dbg!(unsafe {*pc}) as isize) as *mut u32) }; dbg!(decode_execute(insr, &mut state, &mut ConsoleTracer)); - }) + let branch_taken = unsafe { (state.data.as_mut_ptr().byte_offset(14856) as *mut bool) }; + if !unsafe {*branch_taken} { + unsafe { *pc += 4}; + } + + unsafe {*branch_taken = false}; + } } } } else { @@ -264,6 +339,17 @@ pub fn sail_to_brig>( } } + impl, L> core::ops::BitXor for Bundle { + type Output = Self; + + fn bitxor(self, rhs: Self) -> Self::Output { + Self { + value: self.value ^ rhs.value, + length: self.length + } + } + } + impl, L> core::ops::Shl for Bundle { type Output = Self; diff --git a/borealis/src/rudder/build.rs b/borealis/src/rudder/build.rs index 16b4491..b1db255 100644 --- a/borealis/src/rudder/build.rs +++ b/borealis/src/rudder/build.rs @@ -69,6 +69,8 @@ impl BuildContext { self.registers .insert(name, (typ.clone(), self.next_register_offset)); + log::warn!("adding register {name} @ {:x}", self.next_register_offset); + // 8 byte aligned self.next_register_offset += typ.width_bytes().next_multiple_of(8) } @@ -652,13 +654,14 @@ impl<'ctx: 'fn_ctx, 'fn_ctx> BlockBuildContext<'ctx, 'fn_ctx> { length: len, })) } - "eq_bits" | "eq_int" | "eq_any" => Some(self.statement_builder.build( - StatementKind::BinaryOperation { - kind: BinaryOperationKind::CompareEqual, - lhs: args[0].clone(), - rhs: args[1].clone(), - }, - )), + "eq_bits" | "eq_int" | "eq_any" | "eq_any" => Some( + self.statement_builder + .build(StatementKind::BinaryOperation { + kind: BinaryOperationKind::CompareEqual, + lhs: args[0].clone(), + rhs: args[1].clone(), + }), + ), "neq_bits" => Some( self.statement_builder .build(StatementKind::BinaryOperation { @@ -667,7 +670,7 @@ impl<'ctx: 'fn_ctx, 'fn_ctx> BlockBuildContext<'ctx, 'fn_ctx> { rhs: args[1].clone(), }), ), - "add_atom" | "add_bits" => Some(self.statement_builder.build( + "add_atom" | "add_bits" | "add_bits_int" => Some(self.statement_builder.build( StatementKind::BinaryOperation { kind: BinaryOperationKind::Add, lhs: args[0].clone(), @@ -727,6 +730,22 @@ impl<'ctx: 'fn_ctx, 'fn_ctx> BlockBuildContext<'ctx, 'fn_ctx> { rhs: args[1].clone(), }), ), + "xor_vec" => Some( + self.statement_builder + .build(StatementKind::BinaryOperation { + kind: BinaryOperationKind::Xor, + lhs: args[0].clone(), + rhs: args[1].clone(), + }), + ), + "or_vec" => Some( + self.statement_builder + .build(StatementKind::BinaryOperation { + kind: BinaryOperationKind::Or, + lhs: args[0].clone(), + rhs: args[1].clone(), + }), + ), "sail_shiftright" => { Some(self.statement_builder.build(StatementKind::ShiftOperation { kind: ShiftOperationKind::LogicalShiftRight, @@ -756,6 +775,13 @@ impl<'ctx: 'fn_ctx, 'fn_ctx> BlockBuildContext<'ctx, 'fn_ctx> { })) } + "plain_vector_access" => { + Some(self.statement_builder.build(StatementKind::ReadElement { + vector: args[0].clone(), + index: args[1].clone(), + })) + } + "bitvector_access" => { let length = self.statement_builder.build(StatementKind::Constant { typ: Rc::new(Type::u64()), @@ -886,7 +912,68 @@ impl<'ctx: 'fn_ctx, 'fn_ctx> BlockBuildContext<'ctx, 'fn_ctx> { }) } // todo: probably wrong - "SignExtend0" => self.generate_cast(args[0].clone(), Rc::new(Type::s64())), + "SignExtend0" => { + let value = args[0].clone(); + let target_length = args[1].clone(); + + let sixtyfour = self.statement_builder.build(StatementKind::Constant { + typ: Rc::new(Type::u8()), + value: rudder::ConstantValue::UnsignedInteger(64), + }); + + let source_length = + self.statement_builder.build(StatementKind::UnbundleLength { + bundle: value.clone(), + }); + + let shift_amount = + self.statement_builder + .build(StatementKind::BinaryOperation { + kind: BinaryOperationKind::Sub, + lhs: sixtyfour.clone(), + rhs: source_length, + }); + + let shift_amount_cast = + self.generate_cast(shift_amount, Rc::new(Type::s64())); + + let shift_amount_bundle = + self.statement_builder.build(StatementKind::Bundle { + value: shift_amount_cast, + length: sixtyfour, + }); + + let value_bundle = self.generate_cast( + value, + Rc::new(Type::Bundled { + value: Rc::new(Type::s64()), + len: Rc::new(Type::u8()), + }), + ); + + // shift left up to top + let left_shift = + self.statement_builder.build(StatementKind::ShiftOperation { + kind: ShiftOperationKind::LogicalShiftLeft, + value: value_bundle, + amount: shift_amount_bundle.clone(), + }); + + // shift right to target length + let right_shift = + self.statement_builder.build(StatementKind::ShiftOperation { + kind: ShiftOperationKind::ArithmeticShiftRight, + value: left_shift, + amount: shift_amount_bundle, + }); + + // explicitly no masking to length + + self.statement_builder.build(StatementKind::Bundle { + value: right_shift, + length: target_length, + }) + } _ => args[0].clone(), }; @@ -1135,84 +1222,13 @@ impl<'ctx: 'fn_ctx, 'fn_ctx> BlockBuildContext<'ctx, 'fn_ctx> { ) } - // "truncate" => Some(self.statement_builder.build(StatementKind::Cast { - // kind: CastOperationKind::Truncate, - // typ: Rc::new(Type::new_primitive( - // rudder::PrimitiveTypeClass::UnsignedInteger, - // 8, - // )), - // value: args[0].clone(), - // })), + "sail_branch_announce" => Some(self.statement_builder.build(StatementKind::Constant { + typ: Rc::new(Type::unit()), + value: rudder::ConstantValue::Unit, + })), + _ => None, } - // if name.as_ref() == "trap" { - // Some(self.statement_builder.build(StatementKind::Trap)) - // } else if name.as_ref() == "read_pc" { - // Some(self.statement_builder.build(StatementKind::ReadPc)) - // } else if name.as_ref() == "vector_subrange_A" { - // // end - start + 1 - // let one = self.statement_builder.build(StatementKind::Constant { - // typ: args[1].typ(), - // value: rudder::ConstantValue::SignedInteger(1), - // }); - // let diff = self - // .statement_builder - // .build(StatementKind::BinaryOperation { - // kind: BinaryOperationKind::Sub, - // lhs: args[2].clone(), - // rhs: args[1].clone(), - // }); - // let len = self - // .statement_builder - // .build(StatementKind::BinaryOperation { - // kind: BinaryOperationKind::Add, - // lhs: diff.clone(), - // rhs: one.clone(), - // }); - - // Some(self.statement_builder.build(StatementKind::BitExtract { - // value: args[0].clone(), - // start: args[1].clone(), - // length: len, - // })) - // } else if name.as_ref() == "slice" { - - // } else if name.as_ref().starts_with("vector_access_A") { - // Some(self.statement_builder.build(StatementKind::ReadElement { - // vector: args[0].clone(), - // index: args[1].clone(), - // })) - // } else if name.as_ref().starts_with("vector_update_B") { - // Some(self.statement_builder.build(StatementKind::MutateElement { - // vector: args[0].clone(), - // value: args[2].clone(), - // index: args[1].clone(), - // })) - // } else if name.as_ref() == "u__raw_GetSlice_int" { - // // u__raw_GetSlice_int(len, n, start) - // Some(self.statement_builder.build(StatementKind::BitExtract { - // value: args[1].clone(), - // start: args[2].clone(), - // length: args[0].clone(), - // })) - // } else if name.as_ref() == "ZeroExtend__0" { - // let value = args[0].clone(); - // let _length = args[1].clone(); - // Some(self.statement_builder.build(StatementKind::Cast { - // kind: CastOperationKind::ZeroExtend, - // typ: Rc::new(Type::u64()), - // value, - // })) - // } else if name.as_ref() == "%i64->%i" { - // let value = args[0].clone(); - // Some(self.statement_builder.build(StatementKind::Cast { - // kind: CastOperationKind::ZeroExtend, - // typ: Rc::new(Type::u64()), - // value, - // })) - // } else { - // None - // } } /// Last statement returned is the value @@ -1326,6 +1342,7 @@ impl<'ctx: 'fn_ctx, 'fn_ctx> BlockBuildContext<'ctx, 'fn_ctx> { self.build_value(value.clone()); // lookup identifier + // todo: parameters should just be read-only local vars? if let Some(symbol) = self.fn_ctx().rudder_fn.get_local_variable(ident) { // copying into local variable let target_typ = symbol.typ(); @@ -1338,6 +1355,26 @@ impl<'ctx: 'fn_ctx, 'fn_ctx> BlockBuildContext<'ctx, 'fn_ctx> { let idx = fields.get(field_name).unwrap(); + let read_var = self + .statement_builder + .build(StatementKind::ReadVariable { symbol }); + + self.statement_builder.build(StatementKind::ReadField { + composite: read_var.clone(), + field: *idx, + }) + } else if let Some(symbol) = self.fn_ctx().rudder_fn.get_parameter(ident) { + // copying into local variable + let target_typ = symbol.typ(); + + let structs = self.ctx().structs.clone(); + let (_, (_, fields)) = structs + .iter() + .find(|(_, (typ, _))| Rc::ptr_eq(&target_typ, typ)) + .expect("failed to find struct :("); + + let idx = fields.get(field_name).unwrap(); + let read_var = self .statement_builder .build(StatementKind::ReadVariable { symbol }); @@ -1586,8 +1623,59 @@ impl<'ctx: 'fn_ctx, 'fn_ctx> BlockBuildContext<'ctx, 'fn_ctx> { self.generate_cast(value, destination_type) } + // bundle to bundle + ( + Type::Bundled { .. }, + Type::Bundled { + value: dest_value_type, + len: dest_len_type, + }, + ) => { + let source_value = self.statement_builder.build(StatementKind::UnbundleValue { + bundle: source.clone(), + }); + let source_len = self + .statement_builder + .build(StatementKind::UnbundleValue { bundle: source }); + + let cast_value = self.generate_cast(source_value, dest_value_type.clone()); + let cast_len = self.generate_cast(source_len, dest_len_type.clone()); + + self.statement_builder.build(StatementKind::Bundle { + value: cast_value, + length: cast_len, + }) + } + + ( + Type::Vector { + element_count: src_count, + element_type: src_type, + }, + Type::Vector { + element_count: dst_count, + element_type: dst_type, + }, + ) => { + if src_type != dst_type { + todo!(); + } + + if *src_count > 0 && *dst_count == 0 { + // casting known to unknown + self.statement_builder.build(StatementKind::Cast { + kind: CastOperationKind::Convert, + typ: destination_type, + value: source, + }) + } else { + todo!() + } + } + (src, dst) => { - panic!("cannot cast from {src} to {dst}"); + log::warn!("cannot cast from {src} to {dst}"); + return source; } } } diff --git a/borealis/src/rudder/mod.rs b/borealis/src/rudder/mod.rs index 9ee0956..0a174a9 100644 --- a/borealis/src/rudder/mod.rs +++ b/borealis/src/rudder/mod.rs @@ -94,10 +94,11 @@ impl Type { Self::Vector { element_count, element_type, - } => element_type.width_bits() * element_count, + } => element_type.width_bits().max(8) * element_count, Self::Bundled { value, .. } => value.width_bits(), } } + pub fn width_bytes(&self) -> usize { self.width_bits().div_ceil(8) } @@ -139,6 +140,37 @@ impl Type { } } + pub fn is_unknown_length_vector(&self) -> bool { + matches!( + self, + Self::Vector { + element_count: 0, + .. + } + ) + } + + pub fn as_signed(&self) -> Self { + match &*self { + Self::Primitive(PrimitiveType { + tc: PrimitiveTypeClass::UnsignedInteger, + element_width_in_bits, + }) => Self::Primitive(PrimitiveType { + tc: PrimitiveTypeClass::SignedInteger, + element_width_in_bits: *element_width_in_bits, + }), + + Self::Bundled { value, len } => Self::Bundled { + value: Rc::new(value.as_signed()), + len: len.clone(), + }, + + _ => { + panic!("cannot convert to signed: {}", self); + } + } + } + /*pub fn is_integer(&self) -> bool { matches!( self.tc,