Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

run all test on arm/aarch64 #230

Merged
merged 13 commits into from
Jan 8, 2017
185 changes: 172 additions & 13 deletions lisp/c/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,9 +610,11 @@ pointer args[];
#else /* IRIX */

/* not IRIS */
#if x86_64
#if (x86_64 || aarch64)
extern long exec_function_i(void (*)(), long *, long *, long, long *);
extern long exec_function_f(void (*)(), long *, long *, long, long *);

#if x86_64
// func %rdi
// iargv %rsi
// fargv %rdx
Expand Down Expand Up @@ -708,6 +710,157 @@ __asm__ (".align 8\n"
"pop %rbx\n\t"
"retq"
);
#endif
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YoheiKakiuchi このコードってどうやって作るんですか?

#395 見ているんだけど,

#include <stdio.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <setjmp.h>
#include <errno.h>

#include <dlfcn.h>

#include <eus.h> // include eus.h just for eusfloat_t ...                                 

union god{
  int body;
  float spirit;
};

union god human;
union god monkey;

void _test1(int i ) {
  monkey.body = i;
  printf("_test1: %d %f\n", monkey.body, monkey.spirit);
}

void _test2(int i , float f) {
  monkey.body = i;
  printf("_test2: %d %f\n", i, f);
  printf("_test2: %d %f\n", monkey.body, monkey.spirit);
}

int main(int argc, char **argv)
{
  float malice = 2.5;
  human.spirit = malice;
  printf("%ld %ld\n", sizeof(float), sizeof(int));
  printf("main : %d %f\n", human.body, human.spirit);

  printf("_test1(human.body)\n");
  _test1(human.body);

  printf("_test2(human.body, human.spirit)\n");
  _test2(human.body, human.spirit);


  eusinteger_t (*ifunc)(); /* ???? */
  void * handle = dlopen("libtestdefforeign.so", RTLD_LAZY);
  if (!handle) {
    fprintf(stderr, "%s\n", dlerror());
    exit(-1);
  }
  //ifunc = (pointer)dlsym((void *)((eusinteger_t)(handle, "test1")));                    
  ifunc = (pointer)dlsym(handle, "test1");

  double (*ffunc)();
  ffunc=(double (*)())ifunc;

  printf("ffunc(human.body, human.spirit)\n");
  ffunc(human.body, human.spirit);

  eusinteger_t cargv[100];
  cargv[0] = human.body;
  cargv[1] = human.body;
  printf("ffunc(cargv[0], cargv[1])\n");
  ffunc(cargv[0], cargv[1]);

  numunion nargv[100];
  nargv[0].ival = human.body;
  nargv[1].fval = human.spirit;
  printf("ffunc(nargv[0], nargv[1])\n");
  ffunc(nargv[0], nargv[1]);


  float (*ffunc2)(int, float);
  ffunc2=(float (*)(int, float))ifunc;
  printf("ffunc(human.body, human.spirit)\n");
  ffunc(human.body, human.spirit);

  return 0;
}
 (gcc  -DLinux -DGCC -I/root/jskeus/eus/lisp/c -falign-functions=4 -o hoge hoge.c -ldl && ./hoge)

みたいにしているんだけど,これでも上手くいかないので,exec_function_iみたいなのを作らないといけないのかな,って.よく分かっていないんですが.


#if aarch64
__asm__ (".align 8\n"
"exec_function_i:\n\t"
"sub sp, sp, #192\n\t" // 128(8x16) + 64
"stp x29, x30, [sp, 128]\n\t"
"add x29, sp, 128\n\t"
"str x0, [x29, 56]\n\t" // fc
"str x1, [x29, 48]\n\t" // iargv
"str x2, [x29, 40]\n\t" // fargv
"str x3, [x29, 32]\n\t" // vargc
"str x4, [x29, 24]\n\t" // vargv
// vargv -> stack
"mov x1, 0\n\t"
"ldr x2, [x29, 24]\n\t"
"b .FUNCII_LPCK\n\t"
".FUNCII_LP:\n\t"
"lsl x0, x1, 3\n\t"
"add x3, x2, x0\n\t" // vargv[i]
"add x4, sp, x0\n\t" // stack[i]
"ldr x0, [x3]\n\t"
"str x0, [x4]\n\t" // push stack
"add x1, x1, 1\n\t"
".FUNCII_LPCK:\n\t"
"ldr x5, [x29, 32]\n\t"
"cmp x1, x5\n\t"
"blt .FUNCII_LP\n\t"
// fargv -> register
"ldr x0, [x29, 40]\n\t" // fargv
"ldr d0, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d1, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d2, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d3, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d4, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d5, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d6, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d7, [x0]\n\t"
// iargv -> register
"ldr x0, [x29, 48]\n\t" // iargv
"ldr x9, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x1, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x2, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x3, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x4, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x5, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x6, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x7, [x0]\n\t"
// function call
"ldr x8, [x29, 56]\n\t"
"mov x0, x9\n\t"
"blr x8\n\t"
"add sp, x29, 0\n\t"
"ldp x29, x30, [sp], 64\n\t"
"ret"
);

__asm__ (".align 8\n"
"exec_function_f:\n\t"
"sub sp, sp, #192\n\t" // 128(8x16) + 64
"stp x29, x30, [sp, 128]\n\t"
"add x29, sp, 128\n\t"
"str x0, [x29, 56]\n\t" // fc
"str x1, [x29, 48]\n\t" // iargv
"str x2, [x29, 40]\n\t" // fargv
"str x3, [x29, 32]\n\t" // vargc
"str x4, [x29, 24]\n\t" // vargv
// vargv -> stack
"mov x1, 0\n\t"
"ldr x2, [x29, 24]\n\t"
"b .FUNCFF_LPCK\n\t"
".FUNCFF_LP:\n\t"
"lsl x0, x1, 3\n\t"
"add x3, x2, x0\n\t" // vargv[i]
"add x4, sp, x0\n\t" // stack[i]
"ldr x0, [x3]\n\t"
"str x0, [x4]\n\t" // push stack
"add x1, x1, 1\n\t"
".FUNCFF_LPCK:\n\t"
"ldr x5, [x29, 32]\n\t"
"cmp x1, x5\n\t"
"blt .FUNCFF_LP\n\t"
// fargv -> register
"ldr x0, [x29, 40]\n\t" // fargv
"ldr d0, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d1, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d2, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d3, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d4, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d5, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d6, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr d7, [x0]\n\t"
// iargv -> register
"ldr x0, [x29, 48]\n\t" // iargv
"ldr x9, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x1, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x2, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x3, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x4, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x5, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x6, [x0]\n\t"
"add x0, x0, 8\n\t"
"ldr x7, [x0]\n\t"
// function call
"ldr x8, [x29, 56]\n\t"
"mov x0, x9\n\t"
"blr x8\n\t"
"str d0, [x29, 56]\n\t"
"ldr x0, [x29, 56]\n\t"
"add sp, x29, 0\n\t"
"ldp x29, x30, [sp], 64\n\t"
"ret"
);
#endif

#if x86_64
#define NUM_INT_ARGUMENTS 6
#define NUM_FLT_ARGUMENTS 8
#define NUM_EXTRA_ARGUMENTS 16
#elif aarch64
#define NUM_INT_ARGUMENTS 8
#define NUM_FLT_ARGUMENTS 8
#define NUM_EXTRA_ARGUMENTS 16
#endif

pointer call_foreign(ifunc,code,n,args)
eusinteger_t (*ifunc)(); /* ???? */
Expand All @@ -718,9 +871,9 @@ pointer args[];
pointer paramtypes=code->c.fcode.paramtypes;
pointer resulttype=code->c.fcode.resulttype;
pointer p,lisparg;
eusinteger_t iargv[6];
eusinteger_t fargv[8];
eusinteger_t vargv[16];
eusinteger_t iargv[NUM_INT_ARGUMENTS];
eusinteger_t fargv[NUM_FLT_ARGUMENTS];
eusinteger_t vargv[NUM_EXTRA_ARGUMENTS];
int icntr = 0, fcntr = 0, vcntr = 0;

numunion nu;
Expand All @@ -746,46 +899,52 @@ pointer args[];
lisparg=args[j++];
if (p==K_INTEGER) {
c = isint(lisparg)?intval(lisparg):bigintval(lisparg);
if(icntr < 6) iargv[icntr++] = c; else vargv[vcntr++] = c;
if(icntr < NUM_INT_ARGUMENTS) iargv[icntr++] = c; else vargv[vcntr++] = c;
} else if (p==K_STRING) {
if (elmtypeof(lisparg)==ELM_FOREIGN) c=lisparg->c.ivec.iv[0];
else c=(eusinteger_t)(lisparg->c.str.chars);
if(icntr < 6) iargv[icntr++] = c; else vargv[vcntr++] = c;
if(icntr < NUM_INT_ARGUMENTS) iargv[icntr++] = c; else vargv[vcntr++] = c;
} else if (p==K_FLOAT32) {
numbox.f=(float)ckfltval(lisparg);
c=((eusinteger_t)numbox.i.i1) & 0x00000000FFFFFFFF;
if(fcntr < 8) fargv[fcntr++] = c; else vargv[vcntr++] = c;
if(fcntr < NUM_FLT_ARGUMENTS) fargv[fcntr++] = c; else vargv[vcntr++] = c;
} else if (p==K_DOUBLE || p==K_FLOAT) {
numbox.d=ckfltval(lisparg);
c=numbox.l;
if(fcntr < 8) fargv[fcntr++] = c; else vargv[vcntr++] = c;
if(fcntr < NUM_FLT_ARGUMENTS) fargv[fcntr++] = c; else vargv[vcntr++] = c;
} else error(E_USER,(pointer)"unknown type specifier");
if (vcntr >= NUM_EXTRA_ARGUMENTS) {
error(E_USER,(pointer)"too many number of arguments");
}
}
/* &rest arguments? */
while (j<n) { /* j is the counter for the actual arguments*/
lisparg=args[j++];
if (isint(lisparg)) {
c=intval(lisparg);
if(icntr < 6) iargv[icntr++] = c; else vargv[vcntr++] = c;
if(icntr < NUM_INT_ARGUMENTS) iargv[icntr++] = c; else vargv[vcntr++] = c;
} else if (isflt(lisparg)) {
numbox.d=ckfltval(lisparg); /* i advances independently */
c=numbox.l;
if(fcntr < 8) fargv[fcntr++] = c; else vargv[vcntr++] = c;
if(fcntr < NUM_FLT_ARGUMENTS) fargv[fcntr++] = c; else vargv[vcntr++] = c;
} else if (isvector(lisparg)) {
if (elmtypeof(lisparg)==ELM_FOREIGN) c=lisparg->c.ivec.iv[0];
else c=(eusinteger_t)(lisparg->c.str.chars);
if(icntr < 6) iargv[icntr++] = c; else vargv[vcntr++] = c;
if(icntr < NUM_INT_ARGUMENTS) iargv[icntr++] = c; else vargv[vcntr++] = c;
} else if (isbignum(lisparg)){
if (bigsize(lisparg)==1){
eusinteger_t *xv = bigvec(lisparg);
c=(eusinteger_t)xv[0];
if(icntr < 6) iargv[icntr++] = c; else vargv[vcntr++] = c;
if(icntr < NUM_INT_ARGUMENTS) iargv[icntr++] = c; else vargv[vcntr++] = c;
}else{
fprintf(stderr, "bignum size!=1\n");
}
} else {
c=(eusinteger_t)(lisparg->c.obj.iv);
if(icntr < 6) iargv[icntr++] = c; else vargv[vcntr++] = c;
if(icntr < NUM_INT_ARGUMENTS) iargv[icntr++] = c; else vargv[vcntr++] = c;
}
if (vcntr >= NUM_EXTRA_ARGUMENTS) {
error(E_USER,(pointer)"too many number of arguments");
}
}
/**/
Expand Down