Mercurial > hg > CbC > CbC_examples
view ljtes/ljtes_as2.c @ 24:19160c497905
lj_as2: can compile -O2 (can't execute)
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 31 Jan 2016 19:37:36 +0900 |
parents | facab2ddc380 |
children | 6324b8df04f1 |
line wrap: on
line source
#ifdef GCC #define __environment _CbC_environment #define __return _CbC_return #endif #define LOOP 5000000 #include <stdio.h> struct __CbC_env{ void *ret_p,*env; }; int save_env(void *env); __code factorial(int n,int result,int orig,__code(*print)(int,int,int,__code(*)(),void*), void *exit1env) { if (n<0) { printf("#0008:err %d!\n",n); goto return_cs(0,exit1env); } if (n==0) goto (*print)(n,result,orig,print,exit1env); else { result += n; n--; goto factorial(n,result,orig,print,exit1env); } } int calc(int n){ volatile void *env = ({ volatile struct __CbC_env __CbC_environment; env = &__CbC_environment; jmp_buf env_buf; int retval; __CbC_environment.ret_p = &retval; __CbC_environment.env = &env_buf; if (save_env(__CbC_environment.env)){ return retval; } &__CbC_environment; }); goto factorial(n,1,n,print,(void*)env); return 0; } int main( int ac, char *av[]) { int i; long ans; for(i=LOOP,ans=0;i>0;i--){ int a = calc(10); ans += a; } printf("%ld\n",ans); } int save_env(void *env){ asm volatile( "movq %%rbp,(%%rdi);" // env.env[1] = %rbp; frame pointer "movq (%%rsp), %%rax;" // get return addres "movq %%rax, 0x8(%%rdi);" // set return addres "popq %%rax;" // fix stack pointer "movq %%rsp, 0x10(%%rdi);" // set stack pointer "movl $0, %%eax;" // set return value "jmpq *0x8(%%rdi);" // return :"+D"(env)::"rax"); return 0; } __code return_cs(int val, void* env){ asm volatile( "movq (%%rdi), %%r10;" // %r10 = env.ret_p (return value) "movq %%rcx ,(%%r10);" // set return value "movq 0x8(%%rdi), %%r10;" // %r10 = env.env (environment) "movq (%%r10), %%rbp;" // restore frame pointer "movq 0x10(%%r10), %%rsp;" // restore stack pointer "movl $1, %%eax;" // set return value "jmpq *0x8(%%r10);" // return :"+D"(env):"c"(val):"r10","eax"); } __code print(int n,int result,int orig,__code(*print)(),void*exit1env) { goto return_cs(result, exit1env); }