#![cfg_attr(not(feature = "std"), no_std)]
#![forbid(unsafe_code)]
#![allow(
clippy::cast_possible_truncation,
clippy::cast_sign_loss,
clippy::cast_lossless,
clippy::cast_possible_wrap,
clippy::unreadable_literal,
clippy::match_same_arms,
clippy::redundant_closure_for_method_calls,
clippy::bool_to_int_with_if,
clippy::wildcard_imports,
clippy::enum_glob_use,
clippy::needless_raw_string_hashes,
clippy::semicolon_if_nothing_returned,
clippy::must_use_candidate,
clippy::module_name_repetitions,
clippy::uninlined_format_args,
clippy::doc_markdown,
clippy::similar_names,
clippy::case_sensitive_file_extension_comparisons,
clippy::fn_params_excessive_bools,
clippy::too_many_lines,
clippy::single_match_else,
clippy::manual_let_else,
clippy::unnecessary_wraps,
clippy::unused_self,
clippy::map_unwrap_or,
clippy::many_single_char_names,
clippy::redundant_else,
clippy::return_self_not_must_use,
clippy::missing_errors_doc,
clippy::needless_continue
)]
extern crate alloc;
#[cfg(feature = "aarch64")]
pub(crate) mod aarch64;
#[cfg(feature = "arm")]
pub(crate) mod arm;
pub mod assembler;
pub mod encoder;
pub mod error;
pub mod ir;
pub mod lexer;
pub mod linker;
pub mod optimize;
pub mod parser;
pub mod preprocessor;
#[cfg(feature = "riscv")]
pub(crate) mod riscv;
#[cfg(any(feature = "x86", feature = "x86_64"))]
pub(crate) mod x86;
pub use assembler::{Assembler, AssemblyResult, ResourceLimits};
pub use encoder::RelocKind;
pub use error::{ArchName, AsmError, Span};
pub use ir::{
AddrMode, AlignDirective, Arch, BroadcastMode, ConstDef, DataDecl, DataSize, DataValue, Expr,
FillDirective, Instruction, MemoryOperand, Mnemonic, Operand, OperandList, OperandSize,
OptLevel, OrgDirective, Prefix, PrefixList, Register, ShiftAmount, ShiftOp, SpaceDirective,
Statement, SvePredQual, Syntax, VectorArrangement, X86Mode,
};
pub use linker::AppliedRelocation;
pub use preprocessor::Preprocessor;
use alloc::vec::Vec;
pub fn assemble(source: &str, arch: Arch) -> Result<Vec<u8>, AsmError> {
assemble_at(source, arch, 0)
}
pub fn assemble_at(source: &str, arch: Arch, base_addr: u64) -> Result<Vec<u8>, AsmError> {
let mut asm = Assembler::new(arch);
asm.base_address(base_addr);
asm.emit(source)?;
let result = asm.finish()?;
Ok(result.into_bytes())
}
pub fn assemble_with(
source: &str,
arch: Arch,
base_addr: u64,
external_labels: &[(&str, u64)],
) -> Result<Vec<u8>, AsmError> {
let mut asm = Assembler::new(arch);
asm.base_address(base_addr);
for &(name, addr) in external_labels {
asm.define_external(name, addr);
}
asm.emit(source)?;
let result = asm.finish()?;
Ok(result.into_bytes())
}