Attribute, Error, ItemFn, LitStr, Token,
};
+mod inline_assembly;
+
macro_rules! valid_enumerants_as_string {
($enumerant:ident) => {
concat!("`", stringify!($enumerant), "`")
}
}
-#[derive(Debug, Clone)]
-enum AssemblyTextFragment {
- Text(String),
- InputIndex(usize),
- OutputIndex(usize),
-}
-
struct InlineAssembly {
text: Vec<AssemblyTextFragment>,
- text_span: Span,
+ text_span: Option<Span>,
inputs: Vec<TokenStream>,
outputs: Vec<TokenStream>,
clobbers: Vec<TokenStream>,
}
}
+impl From<String> for InlineAssembly {
+ fn from(s: String) -> Self {
+ InlineAssembly {
+ text: vec![AssemblyTextFragment::Text(s)],
+ text_span: None,
+ inputs: Vec::new(),
+ outputs: Vec::new(),
+ clobbers: Vec::new(),
+ }
+ }
+}
+
+impl From<&'_ str> for InlineAssembly {
+ fn from(s: &'_ str) -> Self {
+ String::from(s).into()
+ }
+}
+
impl InlineAssembly {
fn new(text_span: Span) -> Self {
Self {
self.text.push(AssemblyTextFragment::OutputIndex(index));
Ok(())
}
+ fn add_input(&mut self, input: TokenStream) -> usize {
+ let retval = self.inputs.len();
+ self.inputs.push(input);
+ retval
+ }
+ fn add_output(&mut self, output: TokenStream) -> usize {
+ let retval = self.outputs.len();
+ self.outputs.push(output);
+ retval
+ }
}
impl ToTokens for InlineAssembly {
let mut asm = InlineAssembly::new(instruction_name.span());
let mut before_asm = Vec::<TokenStream>::new();
let mut after_asm = Vec::<TokenStream>::new();
- for output in &self.outputs {
- match output {
- InstructionOutput::Rt(span) => {
- unimplemented!("InstructionOutput::Rt");
- }
- InstructionOutput::Carry(span) => {
- unimplemented!("InstructionOutput::Carry");
- }
- InstructionOutput::Overflow(span) => {
- unimplemented!("InstructionOutput::Overflow");
- }
- InstructionOutput::CR0(span) => {
- unimplemented!("InstructionOutput::CR0");
- }
- }
- }
for input in &self.inputs {
match input {
InstructionInput::Ra(span) => {
+ before_asm.push(quote! {let ra = inputs.ra;});
+ let input_index = asm.add_input(quote! {"b"(ra)});
unimplemented!("InstructionInput::Ra");
}
InstructionInput::Rb(span) => {
}
}
}
+ for output in &self.outputs {
+ match output {
+ InstructionOutput::Rt(span) => {
+ unimplemented!("InstructionOutput::Rt");
+ }
+ InstructionOutput::Carry(span) => {
+ unimplemented!("InstructionOutput::Carry");
+ }
+ InstructionOutput::Overflow(span) => {
+ unimplemented!("InstructionOutput::Overflow");
+ }
+ InstructionOutput::CR0(span) => {
+ unimplemented!("InstructionOutput::CR0");
+ }
+ }
+ }
Ok(quote! {
pub fn #fn_name(inputs: InstructionInput) -> InstructionResult {
#![allow(unused_variables, unused_assignments)]
- let InstructionInput {
- ra,
- rb,
- rc,
- carry,
- } = inputs;
- let rt: u64;
- let xer: u64;
- let cr: u32;
#(#before_asm)*
unsafe {
#asm;