import LIB/default-u8.lm; import LIB/default-u16.lm; import LIB/default-u32.lm; import LIB/default-u64.lm; import LIB/default-i8.lm; import LIB/default-i16.lm; import LIB/default-i32.lm; import LIB/default-i64.lm; import LIB/default-string.lm; fragment [] := λ(: l LocalVariable+Array,?>)(: r LocalVariable+U64). (: ( (.program ( \t 'mov \s (.expression l) \[ '%RBP \] , \s '%R15 \n \t 'mov \s (.expression r) \[ '%RBP \] , \s '%R14 \n \t 'add \s '%R14 , \s '%R15 \n \t 'mov \s '0 \[ '%R15 \] , \s '%R15B \n )) (.expression( 'R15B )) ) x+Reg8); fragment [] := λ(: l LocalVariable+Array,?>)(: r LocalVariable+U64). (: ( (.program ( \t 'mov \s (.expression l) \[ '%RBP \] , \s '%R15 \n \t 'mov \s (.expression r) \[ '%RBP \] , \s '%R14 \n \t 'shl \s '$3, '%R14 \n \t 'add \s '%R14 , \s '%R15 \n \t 'mov \s '0 \[ '%R15 \] , \s '%R15 \n )) (.expression( 'R15 )) ) x+Reg64); fragment [] := λ(: l LocalVariable+Array,?>)(: r Constant+U64). (: ( (.program ( \t 'mov \s (.expression l) \[ '%RBP \] , \s '%R15 \n \t 'add \s '$ (*( (.expression r) '8 )) , \s '%R15 \n \t 'mov \s '0 \[ '%R15 \] , \s '%R15 \n )) (.expression( 'R15 )) ) x+Reg64); fragment [] := λ(: l LocalVariable+Field,?>)(: r LocalVariable+U64). (: ( (.program ( \t 'mov \s '%RBP , \s '%R15 \n \t 'add \s '$ (.expression l) , \s '%R15 \n \t 'mov \s (.expression r) \[ '%RBP \] , \s '%R14 \n \t 'shl \s '$3, '%R14 \n \t 'add \s '%R14 , \s '%R15 \n \t 'mov \s '0 \[ '%R15 \] , \s '%R15 \n )) (.expression( 'R15 )) ) x+Reg64); fragment [] := λ(: l LocalVariable+Array)(: r GlobalVariable+U64). (: ( (.program ( \t 'mov \s '$ (.expression l) , \s '%R15 \n \t 'mov \s '$ (.expression r) , \s '%R14 \n \t 'mov \s '0 \[ '%R14 \] , \s '%R14 \n \t 'shl \s '$3 , \s '%R14 \n \t 'add \s '%R14 , \s '%R15 \n \t 'mov \s '0 \[ '%R15 \] , \s '%R15 \n )) (.expression( 'R15 )) ) x+Reg64); fragment set[] := λ(: l LocalVariable+Array,?>,?>)(: i Literal+Constant+U64)(: v Reg64). (: ( (.program ( \t 'mov \s (.expression l) \[ '%RBP \] , \s '%R15 \n \t 'mov \s '% (.expression v) , \s (*( '8 (.expression i) )) \[ '%R15 \] \n )) ) Nil); fragment set[] := λ(: l LocalVariable+Array,?>)(: i Literal+Constant+U64)(: v LocalVariable+Sized<8>). (: ( (.program ( \t 'mov \s (.expression v) \[ '%RBP \] , \s '%R14 \n \t 'mov \s (.expression l) \[ '%RBP \] , \s '%R15 \n \t 'mov \s '%R14 , \s (*( '8 (.expression i) )) \[ '%R15 \] \n )) ) Nil); fragment set[] := λ(: l Reg64+Array,?>)(: i Literal+Constant+U64)(: v LocalVariable+Sized<8>). (: ( (.program ( \t 'mov \s '% (.expression l) , \s '%R15 \n \t 'mov \s (.expression v) \[ '%RBP \] , \s '%R14 \n \t 'mov \s '%R14 , \s (*( '8 (.expression i) )) \[ '%R15 \] \n )) ) Nil); fragment set[] := λ(: l LocalVariable+Array,?>)(: i LocalVariable+U64)(: v Reg8+Sized<1>). (: ( (.program ( \t 'mov \s '% (.expression v) , \s '%R14B \n \t 'mov \s (.expression i) \[ '%RBP \] , \s '%R13 \n \t 'mov \s (.expression l) \[ '%RBP \] , \s '%R15 \n \t 'add \s '%R13 , \s '%R15 \n \t 'mov \s '%R14B , \s '0 \[ '%R15 \] \n )) ) Nil); fragment set[] := λ(: l LocalVariable+Array,?>)(: i LocalVariable+U64)(: v Literal+Constant+Sized<1>). (: ( (.program ( \t 'mov \s (.expression i) \[ '%RBP \] , \s '%R13 \n \t 'mov \s (.expression l) \[ '%RBP \] , \s '%R15 \n \t 'add \s '%R13 , \s '%R15 \n \t 'movb \s '$ (.expression v) , \s '0 \[ '%R15 \] \n )) ) Nil); fragment set[] := λ(: l LocalVariable+Array,?>)(: i LocalVariable+U64)(: v LocalVariable+Sized<1>). (: ( (.program ( \t 'mov \s (.expression v) \[ '%RBP \] , \s '%R14B \n \t 'mov \s (.expression i) \[ '%RBP \] , \s '%R13 \n \t 'mov \s (.expression l) \[ '%RBP \] , \s '%R15 \n \t 'add \s '%R13 , \s '%R15 \n \t 'movb \s '%R14B , \s '0 \[ '%R15 \] \n )) ) Nil); fragment set[] := λ(: dst Reg64+Array,?>)(: src LocalVariable+Sized). (: ( (.program ( (if-eq (.expression size) 1 ( \t 'mov \t (.expression src) \[ '%RBP \] , \s '%R15B \n \t 'mov \s '%R15B , \s 0 \[ '% (.expression dst) \] \n )) (if-eq (.expression size) 2 ( \t 'mov \t (.expression src) \[ '%RBP \] , \s '%R15W \n \t 'mov \s '%R15W , \s 0 \[ '% (.expression dst) \] \n )) (if-eq (.expression size) 4 ( \t 'mov \t (.expression src) \[ '%RBP \] , \s '%R15D \n \t 'mov \s '%R15D , \s 0 \[ '% (.expression dst) \] \n )) (if-eq (.expression size) 8 ( \t 'mov \t (.expression src) \[ '%RBP \] , \s '%R15 \n \t 'mov \s '%R15 , \s 0 \[ '% (.expression dst) \] \n )) (if-eq 1 (>( (.expression size) 8 )) ( (for word-offset in (range( 0 (/( (.expression size) 8 )) )) ( \t 'mov \t (+( (.expression src) (*( 8 (.expression word-offset) )) )) \[ '%RBP \] , \s '%R15 \n \t 'mov \s '%R15 , \s (*( 8 (.expression word-offset) )) \[ '% (.expression dst) \] \n )) )) )) ) Nil); fragment [] := λ(: l GlobalVariable+Array)(: r GlobalVariable+U64). (: ( (.program ( \t 'mov \s '$ (.expression l) , \s '%R15 \n \t 'mov \s '$ (.expression r) , \s '%R14 \n \t 'mov \s '0 \[ '%R14 \] , \s '%R14 \n \t 'shl \s '$3 , \s '%R14 \n \t 'add \s '%R14 , \s '%R15 \n \t 'mov \s '0 \[ '%R15 \] , \s '%R15 \n )) (.expression( 'R15 )) ) x+Reg64); fragment [] := λ(: l GlobalVariable+Array)(: r LocalVariable+U64). (: ( (.program ( \t 'mov \s '$ (.expression l) , \s '%R15 \n \t 'mov \s (.expression r) \[ '%RBP \] , \s '%R14 \n \t 'shl \s '$3 , \s '%R14 \n \t 'add \s '%R14 , \s '%R15 \n \t 'mov \s '0 \[ '%R15 \] , \s '%R15 \n )) (.expression( 'R15 )) ) x+Reg64); fragment [] := λ(: l GlobalVariable+Array)(: r Constant+U64). (: ( (.program ( \t 'mov \s '$ (.expression l) , \s '%R15 \n \t 'mov \s '$ (.expression r) , \s '%R14 \n \t 'shl \s '$3 , \s '%R14 \n \t 'add \s '%R14 , \s '%R15 \n \t 'mov \s '0 \[ '%R15 \] , \s '%R15 \n )) (.expression( 'R15 )) ) x+Reg64); fragment > := λ(: l GlobalVariable+U64)(: r Constant+U64). (: ( (.program ( \t 'mov \s '$ (.expression l) , \s '%R15 \n \t 'mov \s '0 \[ '%R15 \] , \s '%R15 \n \t 'cmp \s '$ (.expression r) , '%R15 \n )) (.expression( 'ja )) ) BranchConditional); fragment > := λ(: l LocalVariable+U64)(: r Constant+U64). (: ( (.program ( \t 'mov \s (.expression l) \[ '%RBP \] , \s '%R15 \n \t 'cmp \s '$ (.expression r) , '%R15 \n )) (.expression( 'ja )) ) BranchConditional); fragment > := λ(: l LocalVariable+U64)(: r LocalVariable+U64). (: ( (.program ( \t 'mov \s (.expression l) \[ '%RBP \] , \s '%R15 \n \t 'mov \s (.expression r) \[ '%RBP \] , \s '%R14 \n \t 'cmp \s '%R14 , '%R15 \n )) (.expression( 'ja )) ) BranchConditional); fragment > := λ(: l LocalVariable+I64)(: r LocalVariable+I64). (: ( (.program ( \t 'mov \s (.expression l) \[ '%RBP \] , \s '%R15 \n \t 'mov \s (.expression r) \[ '%RBP \] , \s '%R14 \n \t 'cmp \s '%R14 , '%R15 \n )) (.expression( 'jg )) ) BranchConditional); fragment > := λ(: l GlobalVariable+I64)(: r Constant+I64). (: ( (.program ( \t 'mov \s '$ (.expression l) , \s '%R15 \n \t 'mov \s '0 \[ '%R15 \] , \s '%R15 \n \t 'cmp \s '$ (.expression r) , '%R15 \n )) (.expression( 'jg )) ) BranchConditional); fragment > := λ(: l LocalVariable+I64)(: r Constant+I64). (: ( (.program ( \t 'mov \s (.expression l) \[ '%RBP \] , \s '%R15 \n \t 'cmp \s '$ (.expression r) , '%R15 \n )) (.expression( 'jg )) ) BranchConditional); fragment << := λ(: l U64+LocalVariable)(: r U64+Constant+Literal). (: ( (.program( \t 'mov \s (.expression l) \[ '%RBP \] , '%RAX \n \t 'shl \s '$ (.expression r) , '%RAX \n )) (.expression 'RAX) ) U64+Reg64); fragment >> := λ(: l U64+LocalVariable)(: r U64+Constant+Literal). (: ( (.program( \t 'mov \s (.expression l) \[ '%RBP \] , '%RAX \n \t 'shr \s '$ (.expression r) , '%RAX \n )) (.expression 'RAX) ) U64+Reg64); fragment branchtrue := λ(: _ Nil). (: ( (.expression( 'jmp )) ) BranchConditional); fragment branchfalse := λ(: _ Nil). (: ( (.program( \t 'cmp \s '%RSP, \s '%RSP \n )) (.expression( 'jne )) ) BranchConditional); fragment as-branch-conditional := λ(: l Reg64). (: ( (.program ( \t 'cmp \s '$0 , \s '% (.expression l) \n )) (.expression( 'jne )) ) BranchConditional); fragment as-branch-conditional := λ(: l Reg32). (: ( (.program ( \t 'cmp \s '$0 , \s '% (.expression l) \n )) (.expression( 'jne )) ) BranchConditional); fragment as-branch-conditional := λ(: l Reg16). (: ( (.program ( \t 'cmp \s '$0 , \s '% (.expression l) \n )) (.expression( 'jne )) ) BranchConditional); fragment as-branch-conditional := λ(: l Reg8). (: ( (.program ( \t 'cmp \s '$0 , \s '% (.expression l) \n )) (.expression( 'jne )) ) BranchConditional); fragment primitive::if := λ: DontChain(: ictx ImplicitContext)(: e1 BranchConditional)(: e2 ?)(: e3 ?). (: ( (.program ( \t 'push \s '%RBP \n (.frame e1) (.program e1) \t (.expression e1) \s (uuid label-true-branch) \n (.frame e2) (.frame e3) (.program e3) (.del e3) (if-eq (>( (.return-size ictx) 8 )) 1 ( \t 'mov \s '%RSP , \s '%R14 \n (.unframe e3) (for ri in (range( 0 (/( (.return-size ictx) 8 )) )) ( \t 'movq \s (-( (-( (.return-size ictx) 8 )) (*( (.expression ri) '8 )) )) \[ '%R14 \] , \s '%R15 \n \t 'movq \s '%R15 , \s (-( (-( (.return-size ictx) 8 )) (*( (.expression ri) '8 )) )) \[ '%RSP \] \n )) )) \t 'jmp \s (uuid label-end) \n (uuid label-true-branch) ': \n (.frame e2) (.program e2) (uuid label-end) ': \n (if-eq (.return-size ictx) 1 (\t 'pop \s '%RAX \n)) (if-eq (.return-size ictx) 2 (\t 'pop \s '%RAX \n)) (if-eq (.return-size ictx) 4 (\t 'pop \s '%RAX \n)) (if-eq (.return-size ictx) 8 (\t 'pop \s '%RAX \n)) \t 'mov \s (.rsp-offset ictx) \[ '%RBP \] , '%RSP \n \t 'add \s '$ (.end-offset ictx) ', \s '%RSP \n )) (.del( (.del e1) (.del e2) )) (.unframe( (.unframe e1) (.unframe e2) \t 'add \s '$8 , \s '%RSP \n )) (.expression( (if-eq (.return-size ictx) 1 'AL) (if-eq (.return-size ictx) 2 'AX) (if-eq (.return-size ictx) 4 'EAX) (if-eq (.return-size ictx) 8 'RAX) )) ) Nil); fragment primitive::while := λ: DontChain(: ictx ImplicitContext)(: e1 BranchConditional)(: e2 ?). (: ( (.program( (uuid label-begin-loop) ': \n (.frame e1) (.program e1) \t (.expression e1) \s (uuid label-do-loop) \n \t 'jmp \s (uuid label-end-loop) \n (uuid label-do-loop) ': \n (.frame e2) (.program e2) (.del e2) (.unframe e2) (.unframe e1) \t 'jmp \s (uuid label-begin-loop) \n (uuid label-end-loop) ': \n (.unframe e1) )) ) Nil); fragment cdecl::call := λ: DontChain(: ictx ImplicitContext)(: args ?). (: ( (.program( \o 'call \s 'function \s (.function-name ictx) \s ': \s (.function-type ictx) \n \t 'push \s '%RBX \n \t 'push \s '%RBP \n \t 'mov \s '%RSP , \s '%RBX \n (.program args) \t 'mov \s '%RBX , \s '%RBP \n \t 'call \s (.function-id ictx) \n \t 'mov \s '%RBP , \s '%RSP \n \t 'pop \s '%RBP \n \t 'pop \s '%RBX \n (if-eq '1 (>( (.return-size ictx) '8 )) ( (if-eq Used (.used ictx) ( (for rsi in (range( '0 (/( (.return-size ictx) '8 )) )) ( \t 'push \s (-( '-32 (.args-size ictx) )) \[ '%RSP \] \n )) )) )) )) (.expression( (if-eq (.return-size ictx) 1 'AL) (if-eq (.return-size ictx) 2 'AX) (if-eq (.return-size ictx) 4 'EAX) (if-eq (.return-size ictx) 8 'RAX) )) ) Nil);