| 639 | } |
| 640 | |
| 641 | pub fn codegen<'a>(&mut self, token: &NodeOwner, region: &mut Region, ops: &mut Assembler) { |
| 642 | let (mut edges, states_row) = self.edges_row(region); |
| 643 | let Region { nodes, ports, sinks, states, .. } = region; |
| 644 | let states_map = states; |
| 645 | let states = states_row; |
| 646 | |
| 647 | let constants = nodes.node_indices().flat_map(|n| { |
| 648 | (nodes[n].ro(token).as_ref() as &dyn Any).downcast_ref::<NodeVariant::Constant>().map(|c| (n, c.0)) |
| 649 | }).collect::<Vec<_>>(); |
| 650 | |
| 651 | let vregs = self.virt_map.iter().map(|(i, vr)| (VReg(*i as u16), vr.backing.unwrap())).collect::<Vec<(_,_)>>(); |
| 652 | use crate::petgraph::visit::IntoEdgeReferences; |
| 653 | // this is messy and state edges should probably work differently |
| 654 | //let states_row = ports.edge_references().flat_map(|e| { |
| 655 | // if let OptionalStorage(Some(Storage::Immaterial(Some(state)))) = ports[e.target()].storage { |
| 656 | // ports[e.target()].node.map(|n| Some((n, state))).iter() |
| 657 | // //.chain(ports[e.source()].node.map(|n| Some((n, state))).iter()) |
| 658 | // .flatten().map(|(n, state)| (n, state, nodes[n].sources().iter().find(|)).map(Clone::clone).collect::<Vec<_>>() |
| 659 | // } else { |
| 660 | // vec![] |
| 661 | // } |
| 662 | //}).collect::<Vec<_>>(); |
| 663 | |
| 664 | let mut clock = Timestamp::new(); |
| 665 | self.roots.sort_by(|a, b| nodes[a.0].time.cmp(&nodes[b.0].time)); |
| 666 | let mut blocks = HashMap::new(); |
| 667 | let mut binder = ascent_run! { |
| 668 | struct VarBinder; |
| 669 | // Indicated that Edge from A->B is the Nth input of B, which uses Vreg for storage |
| 670 | //relation edge(crate::port::PortEdge, Option<NodeIdx>, Option<NodeIdx>, usize, VReg) = |
| 671 | // edges; |
| 672 | // The physical register used for each vreg |
| 673 | relation vreg(VReg, RegSpec) = vregs; |
| 674 | // Indicates that Edge from A->B is the Nth output of A and Mth input of B, and uses State |
| 675 | //relation state(crate::port::PortEdge, Option<NodeIdx>, Option<NodeIdx>, Option<usize>, Option<usize>, u16) = |
| 676 | // states; |
| 677 | // Nodes that are constant values |
| 678 | relation constant(NodeIdx, isize) = constants; |
| 679 | // Output the annotations that a node was given |
| 680 | lattice pattern(NodeIdx, Pattern, Set<NodeIdx>) = self.roots.clone(); |
| 681 | relation emit(NodeIdx, CodegenFn); |
| 682 | |
| 683 | // emit constants |
| 684 | emit(c, CodegenFn(box move |ops| dynasm!(ops ;mov Rq(r0.num()), QWORD imm as i64))) <-- |
| 685 | //edge(e, ?Some(c), _, _, r), |
| 686 | pattern(c, const_pattern, _), |
| 687 | if let (Pattern::Constant8(vreg) |
| 688 | |Pattern::Constant16(vreg) |
| 689 | |Pattern::Constant32(vreg) |
| 690 | |Pattern::Constant64(vreg)) = const_pattern, |
| 691 | vreg(vreg, ?&r0), |
| 692 | constant(c, ?&imm) if { println!("constant with r0 class {:?}", r0.class()); r0.class() } == register_class::Q; |
| 693 | |
| 694 | // emit adds |
| 695 | emit(add, CodegenFn(box move |ops| dynasm!(ops; add Rq(r_out.num()), Rq(r_in.num()) ))) <-- |
| 696 | pattern(add, ?Pattern::AddRegReg(vr_out, vr_in), _), |
| 697 | vreg(vr_out, ?&r_out), |
| 698 | vreg(vr_in, ?&r_in), |