
fragment type Reg8  AL  | BL  | CL  | DL  | SIL | DIL | BPL | SPL | R8B | R9B | R10B | R11B | R12B | R13B | R14B | R15B; size Reg8 1;
fragment type Reg16 AX  | BX  | CX  | DX  | SI  | DI  | BP  | SP  | R8W | R9W | R10W | R11W | R12W | R13W | R14W | R15W; size Reg16 2;
fragment type Reg32 EAX | EBX | ECX | EDX | ESI | EDI | EBP | ESP | R8D | R9D | R10D | R11D | R12D | R13D | R14D | R15D; size Reg32 4;
fragment type Reg64 RAX | RBX | RCX | RDX | RSI | RDI | RBP | RSP | R8  | R9  | R10  | R11  | R12  | R13  | R14  | R15;  size Reg64 8;

fragment syscall := λ. (: (.program( \t 'syscall \n )) Nil);

fragment cdecl::return := λ(: l Nil). (: () Nil);
fragment cdecl::return := λ(: l Reg8). (: (  (.program( \t 'mov \t '% (.expression l) , '%al \n))  (.expression 'al)  ) Nil);
fragment cdecl::return := λ(: l Reg16). (: (  (.program( \t 'mov \t '% (.expression l) , '%ax \n))  (.expression 'ax)  ) Nil);
fragment cdecl::return := λ(: l Reg32). (: (  (.program( \t 'mov \t '% (.expression l) , '%eax \n))  (.expression 'eax)  ) Nil);
fragment cdecl::return := λ(: l Reg64). (: (  (.program( \t 'mov \t '% (.expression l) , '%rax \n))  (.expression 'rax)  ) Nil);
fragment cdecl::return := λ(: l Constant+Literal+Sized<1>). (: (  (.program( \t 'mov \t '$ (.expression l) , '%al \n))  (.expression 'al)  ) Nil);
fragment cdecl::return := λ(: l Constant+Literal+Sized<2>). (: (  (.program( \t 'mov \t '$ (.expression l) , '%ax \n))  (.expression 'ax)  ) Nil);
fragment cdecl::return := λ(: l Constant+Literal+Sized<4>). (: (  (.program( \t 'mov \t '$ (.expression l) , '%eax \n))  (.expression 'eax)  ) Nil);
fragment cdecl::return := λ(: l Constant+Literal+Sized<8>). (: (  (.program( \t 'mov \t '$ (.expression l) , '%rax \n))  (.expression 'rax)  ) Nil);
fragment cdecl::return := λ(: l LocalVariable+Sized<1>). (: (  (.program( \t 'mov \t (.expression l) \[ '%rbp \] , '%al \n))  (.expression 'al)  ) Nil);
fragment cdecl::return := λ(: l LocalVariable+Sized<2>). (: (  (.program( \t 'mov \t (.expression l) \[ '%rbp \] , '%ax \n))  (.expression 'ax)  ) Nil);
fragment cdecl::return := λ(: l LocalVariable+Sized<4>). (: (  (.program( \t 'mov \t (.expression l) \[ '%rbp \] , '%eax \n))  (.expression 'eax)  ) Nil);
fragment cdecl::return := λ(: l LocalVariable+Sized<8>). (: (  (.program( \t 'mov \t (.expression l) \[ '%rbp \] , '%rax \n))  (.expression 'rax)  ) Nil);

fragment & := λ(: src LocalVariable). (: ( (.program( \t 'mov \t '%rbp , \s '%r12 \n \t 'add \s '$ (.expression src) , \s '%r12 \n) (.expression( 'r12 ))) ) Reg64);

# Generic 'mov Semantics
fragment mov := λ(: src LocalVariable+Sized<size>)(: dst LocalVariable). (: (
   (.program (
      (for word-offset in (range( 0 (/( size 8 )) )) (
         \t 'movq \s (+( (.expression src) (*( word-offset 8 )) )) \[ '%rbp \] , \s '%r15 \n
         \t 'movq \s '%r15 , \s (+(
            (.expression dst)
            (*( word-offset 8 ))
         )) \[ '%rbp \] \n      
      ))
      (if-eq size 4 (
         \t 'mov \s (+( (.expression src) (*( 4  )) )) \[ '%rbp \] , \s '%r15d \n
         \t 'mov \s '%r15d , \s (.expression dst) \[ '%rbp \] \n
      ))
      (if-eq size 2 (
         \t 'mov \s (.expression src) \[ '%rbp \] , \s '%r15w \n
         \t 'mov \s '%r15w , \s (.expression dst) \[ '%rbp \] \n
      ))
      (if-eq size 1 (
         \t 'mov \s (.expression src) \[ '%rbp \] , \s '%r15b \n
         \t 'mov \s '%r15b , \s (.expression dst) \[ '%rbp \] \n
      ))
   ))
) Nil);
fragment mov := λ(: src LocalVariable+Sized<size>)(: dst GlobalVariable). (: (
   (.program (
      \t 'mov \s '$ (.expression dst) , \s '%r14 \n
      (for word-offset in (range( 0 (/( size 8 )) )) (
         \t 'movq \s (+( (.expression src) (*( word-offset 8 )) )) \[ '%rbp \] , \s '%r15 \n
         \t 'movq \s '%r15 , \s (*( word-offset 8 )) \[ '%r14 \] \n
      ))
      (if-eq size 4 (
         \t 'mov \s (+( (.expression src) (*( 4  )) )) \[ '%rbp \] , \s '%r15d \n
         \t 'mov \s '%r15d , \s 0 \[ '%r14 \] \n
      ))
      (if-eq size 2 (
         \t 'mov \s (.expression src) \[ '%rbp \] , \s '%r15w \n
         \t 'mov \s '%r15w , \s 0 \[ '%r14 \] \n
      ))
      (if-eq size 1 (
         \t 'mov \s (.expression src) \[ '%rbp \] , \s '%r15b \n
         \t 'mov \s '%r15b , \s 0 \[ '%r14 \] \n
      ))
   ))
) Nil);
fragment push := λ(: src GlobalVariable+Sized<size>). (: (
   (.program (
      (\t 'mov \s '$ (.expression src) , \s '%r15 \n)
      (for word-offset in (range( 0 (/( size 8 )) )) (
         \t 'pushq \s (+( (+( size -8 )) (inv(*( word-offset 8 ))) )) \[ '%r15 \] \n
      ))
      (if-eq size 4 (
         \t 'mov \s '0 \[ '%r15 \] , \s '%r15d \n
         \t 'push \s '%r15 \n
      ))
      (if-eq size 2 (
         \t 'mov \s '0 \[ '%r15 \] , \s '%r15w \n
         \t 'push \s '%r15 \n
      ))
      (if-eq size 1 (
         \t 'mov \s '0 \[ '%r15 \] , \s '%r15b \n
         \t 'push \s '%r15 \n
      ))
   ))
) Nil);
fragment push := λ(: src LocalVariable+Sized<size>). (: (
   (.program (
      (for word-offset in (range( 0 (/( size 8 )) )) (
         \t 'pushq \s (+(
            (.expression src)
            (+(
               (+( size '-8 ))
               (inv(*( word-offset 8 )))
            ))
         )) \[ '%rbp \] \n
     ))
      (if-eq size 4 (
         \t 'pushq \s (.expression src) \[ '%rbp \] \n
      ))
      (if-eq size 2 (
         \t 'pushq \s (.expression src) \[ '%rbp \] \n
      ))
      (if-eq size 1 (
         \t 'pushq \s (.expression src) \[ '%rbp \] \n
      ))
   ))
) Nil);
fragment push := λ(: src Reg64+Array<Sized<size>,max>)(: index Literal+Constant). (: (
   (.program (
      (for word-offset in (range( 0 (/( size 8 )) )) (
         \t 'pushq \s (+(
            (*( (.expression index) size ))
            (+(
               (+( size '-8 ))
               (inv(*( word-offset 8 )))
            ))
         )) \[ '% (.expression src) \] \n
      ))
      (if-eq size 4 (
         \t 'pushq \s (*( (.expression index) size )) \[ '% (.expression src) \] \n
      ))
      (if-eq size 2 (
         \t 'pushq \s (*( (.expression index) size )) \[ '% (.expression src) \] \n
      ))
      (if-eq size 1 (
         \t 'pushq \s (*( (.expression index) size )) \[ '% (.expression src) \] \n
      ))
   ))
) Nil);
fragment push := λ(: src LocalVariable+Array<Sized<size>,max>)(: index Literal+Constant). (: (
   (.program (
      \t 'mov \s (.expression src) \[ '%rbp \] , \s '%r15 \n
      (for word-offset in (range( 0 (/( size 8 )) )) (
         \t 'pushq \s (+(
            (*( (.expression index) size ))
            (+(
               (+( size '-8 ))
               (inv(*( word-offset 8 )))
            ))
         )) \[ '%r15 \] \n
      ))
      (if-eq size 4 (
         \t 'pushq \s (+( (.expression src) (*( (.expression index) size )) )) \[ '%r15 \] \n
      ))
      (if-eq size 2 (
         \t 'pushq \s (+( (.expression src) (*( (.expression index) size )) )) \[ '%r15 \] \n
      ))
      (if-eq size 1 (
         \t 'pushq \s (+( (.expression src) (*( (.expression index) size )) )) \[ '%r15 \] \n
      ))
   ))
) Nil);

fragment pop := λ(: src LocalVariable+Sized<size>). (: (
   (.program ( for word-offset in (range( 1 (+( (/( size 8 )) 1 )) )) (
      \t 'popq \s (-( (.expression src) (*( word-offset 8 )) )) \[ '%rbp \] \n
   )))
) Nil);

fragment mov := λ(: src LocalVariable+Sized<size>)(: index Literal+Constant)(: dst Reg64+x[]). (: (
   (.program (
      (\t 'mov \s '% (.expression dst) , \s '%r14 \n)
      (\t 'add \s '$ (*( index size )) , \s '%r14 \n)
      (for word-offset in (range( 0 (/( size 8 )) )) (
         \t 'movq \s (+( (.expression src) (*( word-offset 8 )) )) \[ '%rbp \] , \s '%r15 \n
         \t 'movq \s '%r15 , \s (*( word-offset 8 )) \[ '%r14 \] \n
      ))
   ))
) Nil);
fragment mov := λ(: src LocalVariable+Sized<size>)(: index Literal+Constant)(: dst LocalVariable+Array<Sized<size>,?>). (: (
   (.program (
      \t 'mov \s (.expression dst) \[ '%rbp \] , \s '%r14 \n
      (for word-offset in (range( 0 (/( size 8 )) )) (
         \t 'mov \s (+( (+( (*( word-offset 8 )) (.expression src) )) (*( index size )) )) \[ '%rbp \] , '%r15 \n
         \t 'mov \s '%r15 , \s (+( (*( word-offset 8 )) (*( index size )) )) \[ '%r14 \] \n
      ))
      (if-eq size 4 (
         \t 'mov \s (+( (.expression src) (*( index size )) )) \[ '%rbp \] , '%r15d \n
         \t 'mov \s '%r15d , \s (*( index size )) \[ '%r14 \] \n
      ))
      (if-eq size 2 (
         \t 'mov \s (+( (.expression src) (*( index size )) )) \[ '%rbp \] , '%r15w \n
         \t 'mov \s '%r15w , \s (*( index size )) \[ '%r14 \] \n
      ))
      (if-eq size 1 (
         \t 'mov \s (+( (.expression src) (*( index size )) )) \[ '%rbp \] , '%r15b \n
         \t 'mov \s '%r15b , \s (*( index size )) \[ '%r14 \] \n
      ))
   ))
) Nil);
fragment mov := λ(: src Reg64)(: index Literal+Constant)(: dst LocalVariable+Sized<size>). (: (
   (.program (
      (\t 'mov \s '% (.expression src) , \s '%r14 \n)
      (for word-offset in (range( 0 (/( size 8 )) )) (
         \t 'movq \s (*( word-offset 8 )) \[ '%r14 \] , '%r15 \n
         \t 'movq \s '%r15 , \s (+( (.expression dst) (*( word-offset 8 )) )) \[ '%rbp \] \n
      ))
      (if-eq size 4 (
         \t 'movq \s '0 \[ '%r14 \] , \s '%r15 \n
         \t 'movq \s '%r15 , \s (.expression dst) \[ '%rbp \] \n
      ))
      (if-eq size 2 (
         \t 'movq \s '0 \[ '%r14 \] , \s '%r15 \n
         \t 'movq \s '%r15 , \s (.expression dst) \[ '%rbp \] \n
      ))
      (if-eq size 1 (
         \t 'movq \s '0 \[ '%r14 \] , \s '%r15 \n
         \t 'movq \s '%r15 , \s (.expression dst) \[ '%rbp \] \n
      ))
   ))
) Nil);
fragment mov := λ(: src Literal+Constant)(: index Literal+Constant)(: dst LocalVariable+Array<Sized<size>,?>). (: (
   (.program (
      (if-eq size 8 (
         \t 'movq \s '$ (.expression src) , \s (+( (.expression dst) (*( index size )) )) \[ '%rbp \] \n
      ))
      (if-eq size 4 (
         \t 'movl \s '$ (.expression src) , \s (+( (.expression dst) (*( index size )) )) \[ '%rbp \] \n
      ))
      (if-eq size 2 (
         \t 'movw \s '$ (.expression src) , \s (+( (.expression dst) (*( index size )) )) \[ '%rbp \] \n
      ))
      (if-eq size 1 (
         \t 'movb \s '$ (.expression src) , \s (+( (.expression dst) (*( index size )) )) \[ '%rbp \] \n
      ))
   ))
) Nil);

fragment mov := λ(: src Sized<1>[]+LocalVariable)(: index Literal+Constant)(: dst Reg8). (: (
   (.program(
      \t 'mov \s (.expression src) \[ '%rbp \] , \s '%r15 \n
      \t 'mov \s (.expression index) \[ '%r15 \] , \s '% (.expression dst) \n
   ))
) Nil);

fragment mov := λ(: src LocalVariable)(: dst Constant+Reg64). (: ( (.program( \t 'mov \t (.expression src) \[ '%rbp \] , \s '% (.expression dst) \n)) ) Nil);
fragment mov := λ(: src GlobalVariable)(: dst Constant+Reg64). (: ( (.program(
   \t 'mov \t '$ (.expression src) , \s '% (.expression dst) \n
   \t 'mov \t '0 \[ '% (.expression dst) \] , \s '% (.expression dst) \n
)) ) Nil);
fragment mov := λ(: src Constant+Literal+Sized<8>)(: dst Constant+Reg64). (: ( (.program( \t 'mov \t '$ (.expression src) , \s '% (.expression dst) \n)) ) Nil);
fragment mov := λ(: src Reg64)(: dst Constant+Reg64). (: ( (.program( \t 'mov \t '% (.expression src) , \s '% (.expression dst) \n)) ) Nil);

fragment mov := λ(: src Constant+Literal+Sized<1>)(: dst LocalVariable). (: (.program( \t 'movb \s '$ (.expression src) , \s (.expression dst) \[ '%rbp \] \n )) Nil);
fragment mov := λ(: src Constant+Literal+Sized<2>)(: dst LocalVariable). (: (.program( \t 'movw \s '$ (.expression src) , \s (.expression dst) \[ '%rbp \] \n )) Nil);
fragment mov := λ(: src Constant+Literal+Sized<4>)(: dst LocalVariable). (: (.program( \t 'movl \s '$ (.expression src) , \s (.expression dst) \[ '%rbp \] \n )) Nil);
fragment mov := λ(: src Constant+Literal+Sized<8>)(: dst LocalVariable). (: (.program( \t 'movq \s '$ (.expression src) , \s (.expression dst) \[ '%rbp \] \n )) Nil);

fragment mov := λ(: src Constant+Literal+Sized<1>)(: dst GlobalVariable). (: (.program(
   \t 'mov \s '$ (.expression dst) , \s '%r15 \n
   \t 'movb \s '$ (.expression src) , \s '0 \[ '%r15 \] \n
)) Nil);
fragment mov := λ(: src Constant+Literal+Sized<2>)(: dst GlobalVariable). (: (.program(
   \t 'mov \s '$ (.expression dst) , \s '%r15 \n
   \t 'movw \s '$ (.expression src) , \s '0 \[ '%r15 \] \n
)) Nil);
fragment mov := λ(: src Constant+Literal+Sized<4>)(: dst GlobalVariable). (: (.program(
   \t 'mov \s '$ (.expression dst) , \s '%r15 \n
   \t 'movl \s '$ (.expression src) , \s '0 \[ '%r15 \] \n
)) Nil);
fragment mov := λ(: src Constant+Literal+Sized<8>)(: dst GlobalVariable). (: (.program(
   \t 'mov \s '$ (.expression dst) , \s '%r15 \n
   \t 'movq \s '$ (.expression src) , \s '0 \[ '%r15 \] \n
)) Nil);

fragment push := λ(: src Constant+Literal+Sized<1>). (: (.program( \t 'pushq \s '$ (.expression src) \n )) Nil);
fragment push := λ(: src Constant+Literal+Sized<2>). (: (.program( \t 'pushq \s '$ (.expression src) \n )) Nil);
fragment push := λ(: src Constant+Literal+Sized<4>). (: (.program( \t 'pushq \s '$ (.expression src) \n )) Nil);
fragment push := λ(: src Constant+Literal+Sized<8>). (: (.program( \t 'pushq \s '$ (.expression src) \n )) Nil);

fragment mov := λ(: src Reg8)(: dst LocalVariable). (: (.program( \t 'mov \s '% (.expression src) , \s (.expression dst) \[ '%rbp \] \n )) Nil);
fragment mov := λ(: src Reg16)(: dst LocalVariable). (: (.program( \t 'mov \s '% (.expression src) , \s (.expression dst) \[ '%rbp \] \n )) Nil);
fragment mov := λ(: src Reg32)(: dst LocalVariable). (: (.program( \t 'mov \s '% (.expression src) , \s (.expression dst) \[ '%rbp \] \n )) Nil);
fragment mov := λ(: src Reg64)(: dst LocalVariable). (: (.program( \t 'mov \s '% (.expression src) , \s (.expression dst) \[ '%rbp \] \n )) Nil);

fragment mov := λ(: src Constant+String)(: dst LocalVariable). (: (.program(
   \t 'movq \s '$ (.expression src) , \s (.expression dst) \[ '%rbp \] \n
)) Nil);

fragment mov := λ(: src Reg64)(: dst GlobalVariable). (: (.program(
   \t 'mov \s '% (.expression src) , \s '%r15 \n
   \t 'mov \s '$ (.expression dst) , \s '%r14 \n
   \t 'mov \s '%r15 , \s '0 \[ '%r14 \] \n
)) Nil);

fragment mov := λ(: src GlobalVariable+Sized<1>)(: dst LocalVariable). (: (.program(
   \t 'mov \s '$ (.expression src) , \s '%r15 \n
   \t 'mov \s '0 \[ '%r15 \] , \s '%r15b \n
   \t 'mov \s '%r15b , \s (.expression dst) \[ '%rbp \] \n
)) Nil);
fragment mov := λ(: src GlobalVariable+Sized<2>)(: dst LocalVariable). (: (.program(
   \t 'mov \s '$ (.expression src) , \s '%r15 \n
   \t 'mov \s '0 \[ '%r15 \] , \s '%r15w \n
   \t 'mov \s '%r15w , \s (.expression dst) \[ '%rbp \] \n
)) Nil);
fragment mov := λ(: src GlobalVariable+Sized<4>)(: dst LocalVariable). (: (.program(
   \t 'mov \s '$ (.expression src) , \s '%r15 \n
   \t 'mov \s '0 \[ '%r15 \] , \s '%r15d \n
   \t 'mov \s '%r15d , \s (.expression dst) \[ '%rbp \] \n
)) Nil);
fragment mov := λ(: src GlobalVariable+Sized<8>)(: dst LocalVariable). (: (.program(
   \t 'mov \s '$ (.expression src) , \s '%r15 \n
   \t 'mov \s '0 \[ '%r15 \] , \s '%r15 \n
   \t 'mov \s '%r15 , \s (.expression dst) \[ '%rbp \] \n
)) Nil);

fragment mov := λ(: src LocalVariable)(: dst Reg8). (: (.program( \t 'mov \s (.expression src) \[ '%rbp \] , \s '% (.expression dst) \n )) Nil);
fragment mov := λ(: src LocalVariable)(: dst Reg16). (: (.program( \t 'mov \s (.expression src) \[ '%rbp \] , \s '% (.expression dst) \n )) Nil);
fragment mov := λ(: src LocalVariable)(: dst Reg32). (: (.program( \t 'mov \s (.expression src) \[ '%rbp \] , \s '% (.expression dst) \n )) Nil);
fragment mov := λ(: src LocalVariable)(: dst Reg64). (: (.program( \t 'mov \s (.expression src) \[ '%rbp \] , \s '% (.expression dst) \n )) Nil);

fragment mov := λ(: src Constant+Literal+Sized<1>)(: dst Reg8). (: (.program( \t 'mov \s '$ (.expression src) , \s '% (.expression dst) \n )) Nil);
fragment mov := λ(: src Constant+Literal+Sized<2>)(: dst Reg16). (: (.program( \t 'mov \s '$ (.expression src) , \s '% (.expression dst) \n )) Nil);
fragment mov := λ(: src Constant+Literal+Sized<4>)(: dst Reg32). (: (.program( \t 'mov \s '$ (.expression src) , \s '% (.expression dst) \n )) Nil);
fragment mov := λ(: src Constant+Literal+Sized<8>)(: dst Reg64). (: (.program( \t 'mov \s '$ (.expression src) , \s '% (.expression dst) \n )) Nil);

fragment push := λ(: dst Reg8). (: (.program( \t 'mov \s '% (.expression dst) , '%r15b \n \t 'push \s '%r15 \n )) Nil);
fragment push := λ(: dst Reg16). (: (.program( \t 'mov \s '% (.expression dst) , '%r15w \n \t 'push \s '%r15 \n )) Nil);
fragment push := λ(: dst Reg32). (: (.program( \t 'mov \s '% (.expression dst) , '%r15d \n \t 'push \s '%r15 \n )) Nil);
fragment push := λ(: dst Reg64). (: (.program( \t 'push \s '% (.expression dst) \n )) Nil);

fragment mov := λ(: offset Constant)(: src Reg64)(: dst Reg8). (: (.program( \t 'mov \s (.expression offset) \[ '% (.expression src) \] , \s '% (.expression dst) \n )) Nil);

fragment cmp := λ(: imm Constant+Literal+Sized<8>)(: r Constant+Reg64). (: (.program( \t 'cmp \s '$ (.expression imm) , '% (.expression r) \n )) Nil);
fragment cmp := λ(: imm Constant+Literal+Sized<4>)(: r Constant+Reg32). (: (.program( \t 'cmp \s '$ (.expression imm) , '% (.expression r) \n )) Nil);
fragment cmp := λ(: imm Constant+Literal+Sized<2>)(: r Constant+Reg16). (: (.program( \t 'cmp \s '$ (.expression imm) , '% (.expression r) \n )) Nil);
fragment cmp := λ(: imm Constant+Literal+Sized<1>)(: r Constant+Reg8). (: (.program( \t 'cmp \s '$ (.expression imm) , '% (.expression r) \n )) Nil);

fragment cmp := λ(: l Constant+Reg8)(: r Constant+Reg8). (: (.program( \t 'cmp \s '% (.expression l) , '% (.expression r) \n )) Nil);
fragment cmp := λ(: l Constant+Reg16)(: r Constant+Reg16). (: (.program( \t 'cmp \s '% (.expression l) , '% (.expression r) \n )) Nil);
fragment cmp := λ(: l Constant+Reg32)(: r Constant+Reg32). (: (.program( \t 'cmp \s '% (.expression l) , '% (.expression r) \n )) Nil);
fragment cmp := λ(: l Constant+Reg64)(: r Constant+Reg64). (: (.program( \t 'cmp \s '% (.expression l) , '% (.expression r) \n )) Nil);

fragment movsx := λ(: src Constant+Reg8)(: dst Constant+Reg64). (: (.program( \t 'movsx \s '% (.expression src) , '% (.expression dst) \n )) Nil);
fragment movsx := λ(: src Constant+Reg16)(: dst Constant+Reg64). (: (.program( \t 'movsx \s '% (.expression src) , '% (.expression dst) \n )) Nil);
fragment movsx := λ(: src Constant+Reg32)(: dst Constant+Reg64). (: (.program( \t 'movsx \s '% (.expression src) , '% (.expression dst) \n )) Nil);

fragment jb := λ(: dst Label). (: (.program( \t 'jb \s (.expression dst) \n )) Nil);
fragment jg := λ(: dst Label). (: (.program( \t 'jg \s (.expression dst) \n )) Nil);
fragment jge := λ(: dst Label). (: (.program( \t 'jge \s (.expression dst) \n )) Nil);
fragment jl := λ(: dst Label). (: (.program( \t 'jl \s (.expression dst) \n )) Nil);
fragment jle := λ(: dst Label). (: (.program( \t 'jle \s (.expression dst) \n )) Nil);
fragment je := λ(: dst Label). (: (.program( \t 'je \s (.expression dst) \n )) Nil);
fragment jne := λ(: dst Label). (: (.program( \t 'jne \s (.expression dst) \n )) Nil);
fragment jmp := λ(: dst Label). (: (.program( \t 'jmp \s (.expression dst) \n )) Nil);

fragment neg := λ(: l Reg64). (: (.program( \t 'neg \s '% (.expression l) \n )) Nil);

fragment inc := λ(: l Reg64). (: (.program( \t 'inc \s '% (.expression l) \n )) Nil);

fragment dec := λ(: l Reg64). (: (.program( \t 'dec \s '% (.expression l) \n )) Nil);

fragment div := λ(: l Reg64). (: (.program( \t 'div \s '% (.expression l) \n )) Nil);

fragment add := λ(: src Constant+Literal+Sized<1>)(: dst LocalVariable). (: (.program( \t 'addb \s '$ (.expression src) , \s (.expression dst) \[ '%rbp \] \n )) Nil);
fragment add := λ(: src Constant+Literal+Sized<8>)(: dst Reg64). (: (.program( \t 'addq \s '$ (.expression src) , \s '% (.expression dst) \n )) Nil);

fragment add := λ(: src LocalVariable+Sized<8>)(: dst Reg64). (: (.program( \t 'addq \s (.expression src) \[ '%rbp \] , \s '% (.expression dst) \n )) Nil);

fragment add := λ(: src Reg8)(: dst Reg8). (: (.program( \t 'add \s '% (.expression src) , \s '% (.expression dst) \n )) Nil);
fragment add := λ(: src Reg16)(: dst Reg16). (: (.program( \t 'add \s '% (.expression src) , \s '% (.expression dst) \n )) Nil);
fragment add := λ(: src Reg32)(: dst Reg32). (: (.program( \t 'add \s '% (.expression src) , \s '% (.expression dst) \n )) Nil);
fragment add := λ(: src Reg64)(: dst Reg64). (: (.program( \t 'add \s '% (.expression src) , \s '% (.expression dst) \n )) Nil);

fragment sub := λ(: src Reg8)(: dst Reg8). (: (.program( \t 'sub \s '% (.expression src) , \s '% (.expression dst) \n )) Nil);
fragment sub := λ(: src Reg16)(: dst Reg16). (: (.program( \t 'sub \s '% (.expression src) , \s '% (.expression dst) \n )) Nil);
fragment sub := λ(: src Reg32)(: dst Reg32). (: (.program( \t 'sub \s '% (.expression src) , \s '% (.expression dst) \n )) Nil);
fragment sub := λ(: src Reg64)(: dst Reg64). (: (.program( \t 'sub \s '% (.expression src) , \s '% (.expression dst) \n )) Nil);

fragment push := λ(: l Reg64). (: (.program( \t 'push \s '% (.expression l) \n )) Nil);
fragment pop := λ(: l Reg64). (: (.program( \t 'pop \s '% (.expression l) \n )) Nil);
