0001-append-support-for-csky.patch 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. From 38e46503a1f78166e5f0730133f15bb3cb70f588 Mon Sep 17 00:00:00 2001
  2. From: tianshuliang <tian_shuliang@hoperun.com>
  3. Date: Sun, 25 Apr 2021 13:51:41 +0800
  4. Subject: [PATCH] append support for csky
  5. ---
  6. configure.host | 5 +
  7. src/csky/ffi.c | 395 +++++++++++++++++++++++++++++++++++++++++++
  8. src/csky/ffitarget.h | 63 +++++++
  9. src/csky/sysv.S | 371 ++++++++++++++++++++++++++++++++++++++++
  10. 4 files changed, 834 insertions(+)
  11. create mode 100644 src/csky/ffi.c
  12. create mode 100644 src/csky/ffitarget.h
  13. create mode 100644 src/csky/sysv.S
  14. diff --git a/configure.host b/configure.host
  15. index 9a72cda..3deed6c 100644
  16. --- a/configure.host
  17. +++ b/configure.host
  18. @@ -214,6 +214,11 @@ case "${host}" in
  19. TARGET=RISCV; TARGETDIR=riscv
  20. SOURCES="ffi.c sysv.S"
  21. ;;
  22. +
  23. + csky*-*)
  24. + TARGET=CSKY; TARGETDIR=csky
  25. + SOURCES="ffi.c sysv.S"
  26. + ;;
  27. s390-*-* | s390x-*-*)
  28. TARGET=S390; TARGETDIR=s390
  29. diff --git a/src/csky/ffi.c b/src/csky/ffi.c
  30. new file mode 100644
  31. index 0000000..eb53848
  32. --- /dev/null
  33. +++ b/src/csky/ffi.c
  34. @@ -0,0 +1,395 @@
  35. +/* -----------------------------------------------------------------------
  36. + ffi.c
  37. +
  38. + CSKY Foreign Function Interface
  39. +
  40. + Permission is hereby granted, free of charge, to any person obtaining
  41. + a copy of this software and associated documentation files (the
  42. + ``Software''), to deal in the Software without restriction, including
  43. + without limitation the rights to use, copy, modify, merge, publish,
  44. + distribute, sublicense, and/or sell copies of the Software, and to
  45. + permit persons to whom the Software is furnished to do so, subject to
  46. + the following conditions:
  47. +
  48. + The above copyright notice and this permission notice shall be included
  49. + in all copies or substantial portions of the Software.
  50. +
  51. + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
  52. + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  53. + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  54. + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  55. + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  56. + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  57. + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  58. + DEALINGS IN THE SOFTWARE.
  59. + ----------------------------------------------------------------------- */
  60. +
  61. +#include <ffi.h>
  62. +#include <ffi_common.h>
  63. +
  64. +#include <stdlib.h>
  65. +
  66. +/* ffi_prep_args is called by the assembly routine once stack space
  67. + has been allocated for the function's arguments
  68. +*/
  69. +void ffi_prep_args(char *stack, extended_cif *ecif)
  70. +{
  71. + register unsigned int i;
  72. + register void **p_argv;
  73. + register char *argp;
  74. + register ffi_type **p_arg;
  75. +
  76. + argp = stack;
  77. +
  78. + if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
  79. + *(void **) argp = ecif->rvalue;
  80. + argp += 4;
  81. + }
  82. +
  83. + p_argv = ecif->avalue;
  84. +
  85. + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
  86. + (i != 0);
  87. + i--, p_arg++)
  88. + {
  89. + size_t z;
  90. + size_t alignment;
  91. +
  92. + /* Align if necessary */
  93. + alignment = (*p_arg)->alignment;
  94. +#ifdef __CSKYABIV1__
  95. + /*
  96. + * Adapt ABIV1 bug.
  97. + * If struct's size is larger than 8 bytes, then it always alignment as 4 bytes.
  98. + */
  99. + if (((*p_arg)->type == FFI_TYPE_STRUCT) && ((*p_arg)->size > 8) && (alignment == 8)) {
  100. + alignment = 4;
  101. + }
  102. +#endif
  103. +
  104. + if ((alignment - 1) & (unsigned) argp) {
  105. + argp = (char *) FFI_ALIGN(argp, alignment);
  106. + }
  107. +
  108. + if ((*p_arg)->type == FFI_TYPE_STRUCT)
  109. + argp = (char *) FFI_ALIGN(argp, 4);
  110. +
  111. + z = (*p_arg)->size;
  112. + if (z < sizeof(int))
  113. + {
  114. + z = sizeof(int);
  115. + switch ((*p_arg)->type)
  116. + {
  117. + case FFI_TYPE_SINT8:
  118. + *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
  119. + break;
  120. +
  121. + case FFI_TYPE_UINT8:
  122. + *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
  123. + break;
  124. +
  125. + case FFI_TYPE_SINT16:
  126. + *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
  127. + break;
  128. +
  129. + case FFI_TYPE_UINT16:
  130. + *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
  131. + break;
  132. +
  133. + case FFI_TYPE_STRUCT:
  134. +#ifdef __CSKYBE__
  135. + memcpy((argp + 4 - (*p_arg)->size), *p_argv, (*p_arg)->size);
  136. +#else
  137. + memcpy(argp, *p_argv, (*p_arg)->size);
  138. +#endif
  139. + break;
  140. +
  141. + default:
  142. + FFI_ASSERT(0);
  143. + }
  144. + }
  145. + else if (z == sizeof(int))
  146. + {
  147. + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
  148. + }
  149. + else
  150. + {
  151. + memcpy(argp, *p_argv, z);
  152. + }
  153. + p_argv++;
  154. + argp += z;
  155. + }
  156. +
  157. + return;
  158. +}
  159. +
  160. +/* Perform machine dependent cif processing */
  161. +ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
  162. +{
  163. + /* Round the stack up to a multiple of 8 bytes. This isn't needed
  164. + everywhere, but it is on some platforms, and it doesn't hcsky anything
  165. + when it isn't needed. */
  166. + cif->bytes = (cif->bytes + 7) & ~7;
  167. +
  168. + /* Set the return type flag */
  169. + switch (cif->rtype->type)
  170. + {
  171. +
  172. + case FFI_TYPE_DOUBLE:
  173. + case FFI_TYPE_SINT64:
  174. + case FFI_TYPE_UINT64:
  175. + cif->flags = (unsigned) FFI_TYPE_SINT64;
  176. + break;
  177. +
  178. + case FFI_TYPE_STRUCT:
  179. + if (cif->rtype->size <= 4)
  180. + /* A Composite Type not larger than 4 bytes is returned in r0. */
  181. + cif->flags = (unsigned)FFI_TYPE_INT;
  182. + else if (cif->rtype->size <= 8)
  183. + /* A Composite Type not larger than 8 bytes is returned in r0, r1. */
  184. + cif->flags = (unsigned)FFI_TYPE_SINT64;
  185. + else
  186. + /* A Composite Type larger than 8 bytes, or whose size cannot
  187. + be determined statically ... is stored in memory at an
  188. + address passed [in r0]. */
  189. + cif->flags = (unsigned)FFI_TYPE_STRUCT;
  190. + break;
  191. +
  192. + default:
  193. + cif->flags = FFI_TYPE_INT;
  194. + break;
  195. + }
  196. +
  197. + return FFI_OK;
  198. +}
  199. +
  200. +/* Perform machine dependent cif processing for variadic calls */
  201. +ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
  202. + unsigned int nfixedargs,
  203. + unsigned int ntotalargs)
  204. +{
  205. + return ffi_prep_cif_machdep(cif);
  206. +}
  207. +
  208. +/* Prototypes for assembly functions, in sysv.S */
  209. +extern void ffi_call_SYSV (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *);
  210. +
  211. +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
  212. +{
  213. + extended_cif ecif;
  214. +
  215. + int small_struct = (cif->flags == FFI_TYPE_INT
  216. + && cif->rtype->type == FFI_TYPE_STRUCT);
  217. +
  218. + ecif.cif = cif;
  219. + ecif.avalue = avalue;
  220. +
  221. + unsigned int temp;
  222. +
  223. + /* If the return value is a struct and we don't have a return */
  224. + /* value address then we need to make one */
  225. +
  226. + if ((rvalue == NULL) &&
  227. + (cif->flags == FFI_TYPE_STRUCT))
  228. + {
  229. + ecif.rvalue = alloca(cif->rtype->size);
  230. + }
  231. + else if (small_struct)
  232. + ecif.rvalue = &temp;
  233. + else
  234. + ecif.rvalue = rvalue;
  235. +
  236. + switch (cif->abi)
  237. + {
  238. + case FFI_SYSV:
  239. + ffi_call_SYSV (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
  240. + break;
  241. +
  242. + default:
  243. + FFI_ASSERT(0);
  244. + break;
  245. + }
  246. + if (small_struct)
  247. +#ifdef __CSKYBE__
  248. + memcpy (rvalue, ((unsigned char *)&temp + (4 - cif->rtype->size)), cif->rtype->size);
  249. +#else
  250. + memcpy (rvalue, &temp, cif->rtype->size);
  251. +#endif
  252. +}
  253. +
  254. +/** private members **/
  255. +
  256. +static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
  257. + void** args, ffi_cif* cif);
  258. +
  259. +void ffi_closure_SYSV (ffi_closure *);
  260. +
  261. +/* This function is jumped to by the trampoline */
  262. +
  263. +unsigned int
  264. +ffi_closure_SYSV_inner (closure, respp, args)
  265. + ffi_closure *closure;
  266. + void **respp;
  267. + void *args;
  268. +{
  269. + // our various things...
  270. + ffi_cif *cif;
  271. + void **arg_area;
  272. +
  273. + cif = closure->cif;
  274. + arg_area = (void**) alloca (cif->nargs * sizeof (void*));
  275. +
  276. + /* this call will initialize ARG_AREA, such that each
  277. + * element in that array points to the corresponding
  278. + * value on the stack; and if the function returns
  279. + * a structure, it will re-set RESP to point to the
  280. + * structure return address. */
  281. +
  282. + ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
  283. +
  284. + (closure->fun) (cif, *respp, arg_area, closure->user_data);
  285. +
  286. +#ifdef __CSKYBE__
  287. + if (cif->flags == FFI_TYPE_INT && cif->rtype->type == FFI_TYPE_STRUCT) {
  288. + unsigned int tmp = 0;
  289. + tmp = *(unsigned int *)(*respp);
  290. + *(unsigned int *)(*respp) = (tmp >> ((4 - cif->rtype->size) * 8));
  291. + }
  292. +#endif
  293. +
  294. + return cif->flags;
  295. +}
  296. +
  297. +
  298. +static void
  299. +ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
  300. + void **avalue, ffi_cif *cif)
  301. +{
  302. + register unsigned int i;
  303. + register void **p_argv;
  304. + register char *argp;
  305. + register ffi_type **p_arg;
  306. +
  307. + argp = stack;
  308. +
  309. + if ( cif->flags == FFI_TYPE_STRUCT ) {
  310. + *rvalue = *(void **) argp;
  311. + argp += 4;
  312. + }
  313. +
  314. + p_argv = avalue;
  315. +
  316. + for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
  317. + {
  318. + size_t z;
  319. + size_t alignment;
  320. +
  321. + alignment = (*p_arg)->alignment;
  322. + if (alignment < 4)
  323. + alignment = 4;
  324. +
  325. +#ifdef __CSKYABIV1__
  326. + /*
  327. + * Adapt ABIV1 bug.
  328. + * If struct's size is larger than 8 bytes, then it always alignment as 4 bytes.
  329. + */
  330. + if (((*p_arg)->type == FFI_TYPE_STRUCT) && ((*p_arg)->size > 8) && (alignment == 8)) {
  331. + alignment = 4;
  332. + }
  333. +#endif
  334. +
  335. + /* Align if necessary */
  336. + if ((alignment - 1) & (unsigned) argp) {
  337. + argp = (char *) FFI_ALIGN(argp, alignment);
  338. + }
  339. +
  340. + z = (*p_arg)->size;
  341. +
  342. +#ifdef __CSKYBE__
  343. + unsigned int tmp = 0;
  344. + if ((*p_arg)->size < 4) {
  345. + tmp = *(unsigned int *)argp;
  346. + memcpy(argp, ((unsigned char *)&tmp + (4 - (*p_arg)->size)), (*p_arg)->size);
  347. + }
  348. +#else
  349. + /* because we're little endian, this is what it turns into. */
  350. +#endif
  351. + *p_argv = (void*) argp;
  352. +
  353. + p_argv++;
  354. + argp += z;
  355. + }
  356. +
  357. + return;
  358. +}
  359. +
  360. +/* How to make a trampoline. */
  361. +
  362. +extern unsigned char ffi_csky_trampoline[TRAMPOLINE_SIZE];
  363. +
  364. +/*
  365. + * Since there is no __clear_cache in libgcc in csky toolchain.
  366. + * define ffi_csky_cacheflush in sysv.S.
  367. + * void ffi_csky_cacheflush(uint32 start_addr, uint32 size, int cache)
  368. + */
  369. +#define CACHEFLUSH_IN_FFI 1
  370. +#if CACHEFLUSH_IN_FFI
  371. +extern void ffi_csky_cacheflush(unsigned char *__tramp, unsigned int k,
  372. + int i);
  373. +#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
  374. +({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
  375. + unsigned int __fun = (unsigned int)(FUN); \
  376. + unsigned int __ctx = (unsigned int)(CTX); \
  377. + unsigned char *insns = (unsigned char *)(CTX); \
  378. + memcpy (__tramp, ffi_csky_trampoline, TRAMPOLINE_SIZE); \
  379. + *(unsigned int*) &__tramp[TRAMPOLINE_SIZE] = __ctx; \
  380. + *(unsigned int*) &__tramp[TRAMPOLINE_SIZE + 4] = __fun; \
  381. + ffi_csky_cacheflush(&__tramp[0], TRAMPOLINE_SIZE, 3); /* Clear data mapping. */ \
  382. + ffi_csky_cacheflush(insns, TRAMPOLINE_SIZE, 3); \
  383. + /* Clear instruction \
  384. + mapping. */ \
  385. + })
  386. +#else
  387. +#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
  388. +({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
  389. + unsigned int __fun = (unsigned int)(FUN); \
  390. + unsigned int __ctx = (unsigned int)(CTX); \
  391. + unsigned char *insns = (unsigned char *)(CTX); \
  392. + memcpy (__tramp, ffi_csky_trampoline, TRAMPOLINE_SIZE); \
  393. + *(unsigned int*) &__tramp[TRAMPOLINE_SIZE] = __ctx; \
  394. + *(unsigned int*) &__tramp[TRAMPOLINE_SIZE + 4] = __fun; \
  395. + __clear_cache((&__tramp[0]), (&__tramp[TRAMPOLINE_SIZE-1])); /* Clear data mapping. */ \
  396. + __clear_cache(insns, insns + TRAMPOLINE_SIZE); \
  397. + /* Clear instruction \
  398. + mapping. */ \
  399. + })
  400. +#endif
  401. +
  402. +/* the cif must already be prep'ed */
  403. +
  404. +ffi_status
  405. +ffi_prep_closure_loc (ffi_closure* closure,
  406. + ffi_cif* cif,
  407. + void (*fun)(ffi_cif*,void*,void**,void*),
  408. + void *user_data,
  409. + void *codeloc)
  410. +{
  411. + void (*closure_func)(ffi_closure*) = NULL;
  412. +
  413. + if (cif->abi == FFI_SYSV)
  414. + closure_func = &ffi_closure_SYSV;
  415. + else
  416. + return FFI_BAD_ABI;
  417. +
  418. + FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
  419. + closure_func, \
  420. + codeloc);
  421. +
  422. + closure->cif = cif;
  423. + closure->user_data = user_data;
  424. + closure->fun = fun;
  425. +
  426. + return FFI_OK;
  427. +}
  428. +
  429. +
  430. diff --git a/src/csky/ffitarget.h b/src/csky/ffitarget.h
  431. new file mode 100644
  432. index 0000000..f770aac
  433. --- /dev/null
  434. +++ b/src/csky/ffitarget.h
  435. @@ -0,0 +1,63 @@
  436. +/* -----------------------------------------------------------------*-C-*-
  437. + ffitarget.h - Copyright (c) 2012 Anthony Green
  438. + Copyright (c) 2010 CodeSourcery
  439. + Copyright (c) 1996-2003 Red Hat, Inc.
  440. +
  441. + Target configuration macros for CSKY.
  442. +
  443. + Permission is hereby granted, free of charge, to any person obtaining
  444. + a copy of this software and associated documentation files (the
  445. + ``Software''), to deal in the Software without restriction, including
  446. + without limitation the rights to use, copy, modify, merge, publish,
  447. + distribute, sublicense, and/or sell copies of the Software, and to
  448. + permit persons to whom the Software is furnished to do so, subject to
  449. + the following conditions:
  450. +
  451. + The above copyright notice and this permission notice shall be included
  452. + in all copies or substantial portions of the Software.
  453. +
  454. + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
  455. + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  456. + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  457. + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  458. + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  459. + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  460. + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  461. + DEALINGS IN THE SOFTWARE.
  462. +
  463. + ----------------------------------------------------------------------- */
  464. +
  465. +#ifndef LIBFFI_TARGET_H
  466. +#define LIBFFI_TARGET_H
  467. +
  468. +#ifndef LIBFFI_H
  469. +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
  470. +#endif
  471. +
  472. +#ifndef LIBFFI_ASM
  473. +typedef unsigned long ffi_arg;
  474. +typedef signed long ffi_sarg;
  475. +
  476. +typedef enum ffi_abi {
  477. + FFI_FIRST_ABI = 0,
  478. + FFI_SYSV,
  479. + FFI_LAST_ABI,
  480. + FFI_DEFAULT_ABI = FFI_SYSV,
  481. +} ffi_abi;
  482. +#endif
  483. +
  484. +#ifdef __CSKYABIV2__
  485. +#define FFI_ASM_ARGREG_SIZE 16
  486. +#define TRAMPOLINE_SIZE 16
  487. +#define FFI_TRAMPOLINE_SIZE 24
  488. +#else
  489. +#define FFI_ASM_ARGREG_SIZE 24
  490. +#define TRAMPOLINE_SIZE 20
  491. +#define FFI_TRAMPOLINE_SIZE 28
  492. +#endif
  493. +
  494. +/* ---- Definitions for closures ----------------------------------------- */
  495. +
  496. +#define FFI_CLOSURES 1
  497. +#define FFI_NATIVE_RAW_API 0
  498. +#endif
  499. diff --git a/src/csky/sysv.S b/src/csky/sysv.S
  500. new file mode 100644
  501. index 0000000..962a796
  502. --- /dev/null
  503. +++ b/src/csky/sysv.S
  504. @@ -0,0 +1,371 @@
  505. +/* -----------------------------------------------------------------------
  506. + sysv.S
  507. +
  508. + CSKY Foreign Function Interface
  509. +
  510. + Permission is hereby granted, free of charge, to any person obtaining
  511. + a copy of this software and associated documentation files (the
  512. + ``Software''), to deal in the Software without restriction, including
  513. + without limitation the rights to use, copy, modify, merge, publish,
  514. + distribute, sublicense, and/or sell copies of the Software, and to
  515. + permit persons to whom the Software is furnished to do so, subject to
  516. + the following conditions:
  517. +
  518. + The above copyright notice and this permission notice shall be included
  519. + in all copies or substantial portions of the Software.
  520. +
  521. + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
  522. + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  523. + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  524. + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  525. + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  526. + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  527. + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  528. + DEALINGS IN THE SOFTWARE.
  529. + ----------------------------------------------------------------------- */
  530. +
  531. +#define LIBFFI_ASM
  532. +#include <fficonfig.h>
  533. +#include <ffi.h>
  534. +
  535. +.macro CSKY_FUNC_START name
  536. + .text
  537. + .align 2
  538. + .globl \name
  539. + .type \name, @function
  540. + \name:
  541. +.endm
  542. +
  543. +#ifdef __CSKYABIV2__
  544. +
  545. + /*
  546. + * a0: fn
  547. + * a1: &ecif
  548. + * a2: cif->bytes
  549. + * a3: fig->flags
  550. + * sp+0: ecif.rvalue
  551. + */
  552. +CSKY_FUNC_START ffi_call_SYSV
  553. + /* Save registers */
  554. + .cfi_startproc
  555. + subi sp, 28
  556. + .cfi_def_cfa_offset 28
  557. + stw a0, (sp, 0x0)
  558. + .cfi_offset 0, -28
  559. + stw a1, (sp, 0x4)
  560. + .cfi_offset 1, -24
  561. + stw a2, (sp, 0x8)
  562. + .cfi_offset 2, -20
  563. + stw a3, (sp, 0xC)
  564. + .cfi_offset 3, -16
  565. + stw l0, (sp, 0x10)
  566. + .cfi_offset 4, -12
  567. + stw l1, (sp, 0x14)
  568. + .cfi_offset 5, -8
  569. + stw lr, (sp, 0x18)
  570. + .cfi_offset 15, -4
  571. +
  572. + mov l0, sp
  573. + .cfi_def_cfa_register 4
  574. +
  575. + /* Make room for all of the new args. */
  576. + subu sp, sp, a2
  577. +
  578. + /* Place all of the ffi_prep_args in position */
  579. + mov a0, sp
  580. + /* a1 already set */
  581. +
  582. + /* Call ffi_prep_args(stack, &ecif) */
  583. + jsri ffi_prep_args
  584. +
  585. + /* move first 4 parameters in registers */
  586. + ldw a0, (sp, 0x0)
  587. + ldw a1, (sp, 0x4)
  588. + ldw a2, (sp, 0x8)
  589. + ldw a3, (sp, 0xC)
  590. +
  591. + /* and adjust stack */
  592. + subu lr, l0, sp /* cif->bytes == l0 - sp */
  593. + cmphsi lr, 16
  594. + movi l1, 16
  595. + movt lr, l1
  596. + addu sp, sp, lr
  597. +
  598. + ldw l1, (l0, 0) /* load fn() in advance */
  599. +
  600. + /* call (fn) (...) */
  601. + jsr l1
  602. +
  603. + /* Remove the space we pushed for the args */
  604. + mov sp, l0
  605. +
  606. + /* Load r2 with the pointer to storage for the return value */
  607. + ldw a2, (sp, 0x1C)
  608. +
  609. + /* Load r3 with the return type code */
  610. + ldw a3, (sp, 0xC)
  611. +
  612. + /* If the return value pointer is NULL, assume no return value. */
  613. + cmpnei a2, 0
  614. + bf .Lepilogue
  615. +
  616. + cmpnei a3, FFI_TYPE_STRUCT
  617. + bf .Lepilogue
  618. +
  619. + /* return INT64 */
  620. + cmpnei a3, FFI_TYPE_SINT64
  621. + bt .Lretint
  622. + /* stw a0, (a2, 0x0) at .Lretint */
  623. + stw a1, (a2, 0x4)
  624. +
  625. +.Lretint:
  626. + /* return INT */
  627. + stw a0, (a2, 0x0)
  628. +
  629. +.Lepilogue:
  630. + ldw a0, (sp, 0x0)
  631. + ldw a1, (sp, 0x4)
  632. + ldw a2, (sp, 0x8)
  633. + ldw a3, (sp, 0xC)
  634. + ldw l0, (sp, 0x10)
  635. + ldw l1, (sp, 0x14)
  636. + ldw lr, (sp, 0x18)
  637. + addi sp, sp, 28
  638. + rts
  639. + .cfi_endproc
  640. + .size ffi_call_SYSV, .-ffi_call_SYSV
  641. +
  642. +
  643. + /*
  644. + * unsigned int FFI_HIDDEN
  645. + * ffi_closure_SYSV_inner (closure, respp, args)
  646. + * ffi_closure *closure;
  647. + * void **respp;
  648. + * void *args;
  649. + */
  650. +CSKY_FUNC_START ffi_closure_SYSV
  651. + .cfi_startproc
  652. + mov a2, sp
  653. + addi a1, sp, 16
  654. + subi sp, sp, 24
  655. + .cfi_def_cfa_offset 40
  656. + stw a1, (sp, 0x10)
  657. + .cfi_offset 1, -24
  658. + stw lr, (sp, 0x14)
  659. + .cfi_offset 15, -20
  660. + stw sp, (sp, 0x8)
  661. + addi a1, sp, 8
  662. + jsri ffi_closure_SYSV_inner
  663. + ldw a0, (sp, 0x0)
  664. + /*
  665. + * if FFI_TYPE_SINT64, need a1.
  666. + * if FFI_TYPE_INT, ignore a1.
  667. + */
  668. + ldw a1, (sp, 0x4)
  669. +
  670. + ldw lr, (sp, 0x14)
  671. + addi sp, sp, 40
  672. + rts
  673. + .cfi_endproc
  674. + .size ffi_closure_SYSV, .-ffi_closure_SYSV
  675. +
  676. +CSKY_FUNC_START ffi_csky_trampoline
  677. + subi sp, sp, 16
  678. + stw a0, (sp, 0x0)
  679. + stw a1, (sp, 0x4)
  680. + stw a2, (sp, 0x8)
  681. + stw a3, (sp, 0xC)
  682. + lrw a0, [.Lctx]
  683. + lrw a1, [.Lfun]
  684. + jmp a1
  685. +.Lctx:
  686. + mov a0, a0
  687. + mov a0, a0
  688. +.Lfun:
  689. +
  690. + .size ffi_csky_trampoline, .-ffi_csky_trampoline
  691. +
  692. +CSKY_FUNC_START ffi_csky_cacheflush
  693. + mov t0, r7
  694. + movi r7, 123
  695. + trap 0
  696. + mov r7, t0
  697. + rts
  698. +
  699. + .size ffi_csky_cacheflush, .-ffi_csky_cacheflush
  700. +
  701. +#else /* !__CSKYABIV2__ */
  702. +
  703. + /*
  704. + * a0: fn
  705. + * a1: &ecif
  706. + * a2: cif->bytes
  707. + * a3: fig->flags
  708. + * a4: ecif.rvalue
  709. + */
  710. +CSKY_FUNC_START ffi_call_SYSV
  711. + /* Save registers */
  712. + .cfi_startproc
  713. + subi sp, 32
  714. + subi sp, 8
  715. + .cfi_def_cfa_offset 40
  716. + stw a0, (sp, 0x0)
  717. + .cfi_offset 2, -40
  718. + stw a1, (sp, 0x4)
  719. + .cfi_offset 3, -36
  720. + stw a2, (sp, 0x8)
  721. + .cfi_offset 4, -32
  722. + stw a3, (sp, 0xC)
  723. + .cfi_offset 5, -28
  724. + stw a4, (sp, 0x10)
  725. + .cfi_offset 6, -24
  726. + stw a5, (sp, 0x14)
  727. + .cfi_offset 7, -20
  728. + stw l0, (sp, 0x18)
  729. + .cfi_offset 8, -16
  730. + stw l1, (sp, 0x1C)
  731. + .cfi_offset 9, -12
  732. + stw lr, (sp, 0x20)
  733. + .cfi_offset 15, -8
  734. +
  735. + mov l0, sp
  736. + .cfi_def_cfa_register 8
  737. +
  738. + /* Make room for all of the new args. */
  739. + subu sp, sp, a2
  740. +
  741. + /* Place all of the ffi_prep_args in position */
  742. + mov a0, sp
  743. + /* a1 already set */
  744. +
  745. + /* Call ffi_prep_args(stack, &ecif) */
  746. + jsri ffi_prep_args
  747. +
  748. + /* move first 4 parameters in registers */
  749. + ldw a0, (sp, 0x0)
  750. + ldw a1, (sp, 0x4)
  751. + ldw a2, (sp, 0x8)
  752. + ldw a3, (sp, 0xC)
  753. + ldw a4, (sp, 0x10)
  754. + ldw a5, (sp, 0x14)
  755. +
  756. + /* and adjust stack */
  757. + mov lr, l0
  758. + subu lr, sp /* cif->bytes == l0 - sp */
  759. + movi l1, 24
  760. + cmphs lr, l1
  761. + movt lr, l1
  762. + addu sp, sp, lr
  763. +
  764. + ldw l1, (l0, 0) /* load fn() in advance */
  765. +
  766. + /* call (fn) (...) */
  767. + jsr l1
  768. +
  769. + /* Remove the space we pushed for the args */
  770. + mov sp, l0
  771. +
  772. + /* Load r2 with the pointer to storage for the return value */
  773. + ldw a2, (sp, 0x10)
  774. +
  775. + /* Load r3 with the return type code */
  776. + ldw a3, (sp, 0xC)
  777. +
  778. + /* If the return value pointer is NULL, assume no return value. */
  779. + cmpnei a2, 0
  780. + bf .Lepilogue
  781. +
  782. + cmpnei a3, FFI_TYPE_STRUCT
  783. + bf .Lepilogue
  784. +
  785. + /* return INT64 */
  786. + cmpnei a3, FFI_TYPE_SINT64
  787. + bt .Lretint
  788. + /* stw a0, (a2, 0x0) at .Lretint */
  789. + stw a1, (a2, 0x4)
  790. +
  791. +.Lretint:
  792. + /* return INT */
  793. + stw a0, (a2, 0x0)
  794. +
  795. +.Lepilogue:
  796. + ldw a0, (sp, 0x0)
  797. + ldw a1, (sp, 0x4)
  798. + ldw a2, (sp, 0x8)
  799. + ldw a3, (sp, 0xC)
  800. + ldw a4, (sp, 0x10)
  801. + ldw a5, (sp, 0x14)
  802. + ldw l0, (sp, 0x18)
  803. + ldw l1, (sp, 0x1C)
  804. + ldw lr, (sp, 0x20)
  805. + addi sp, sp, 32
  806. + addi sp, sp, 8
  807. + rts
  808. + .cfi_endproc
  809. +
  810. + .size ffi_call_SYSV, .-ffi_call_SYSV
  811. +
  812. +
  813. + /*
  814. + * unsigned int FFI_HIDDEN
  815. + * ffi_closure_SYSV_inner (closure, respp, args)
  816. + * ffi_closure *closure;
  817. + * void **respp;
  818. + * void *args;
  819. + */
  820. +CSKY_FUNC_START ffi_closure_SYSV
  821. + .cfi_startproc
  822. + mov a2, sp
  823. + mov a1, sp
  824. + addi a1, 24
  825. + subi sp, sp, 24
  826. + .cfi_def_cfa_offset 48
  827. + stw a1, (sp, 0x10)
  828. + .cfi_offset 3, -32
  829. + stw lr, (sp, 0x14)
  830. + .cfi_offset 15, -28
  831. + stw sp, (sp, 0x8)
  832. + mov a1, sp
  833. + addi a1, 8
  834. + jsri ffi_closure_SYSV_inner
  835. + ldw a0, (sp, 0x0)
  836. + /*
  837. + * if FFI_TYPE_SINT64, need a1.
  838. + * if FFI_TYPE_INT, ignore a1.
  839. + */
  840. + ldw a1, (sp, 0x4)
  841. +
  842. + ldw lr, (sp, 0x14)
  843. + addi sp, sp, 24
  844. + addi sp, sp, 24
  845. + rts
  846. + .cfi_endproc
  847. +
  848. + .size ffi_closure_SYSV, .-ffi_closure_SYSV
  849. +
  850. +CSKY_FUNC_START ffi_csky_trampoline
  851. + subi sp, 24
  852. + stw a0, (sp, 0x0)
  853. + stw a1, (sp, 0x4)
  854. + stw a2, (sp, 0x8)
  855. + stw a3, (sp, 0xC)
  856. + stw a4, (sp, 0x10)
  857. + stw a5, (sp, 0x14)
  858. + lrw a0, [.Lctx]
  859. + lrw a1, [.Lfun]
  860. + jmp a1
  861. +.Lctx:
  862. + mov a0, a0
  863. + mov a0, a0
  864. +.Lfun:
  865. +
  866. + .size ffi_csky_trampoline, .-ffi_csky_trampoline
  867. +
  868. +CSKY_FUNC_START ffi_csky_cacheflush
  869. + lrw r1, 123
  870. + trap 0
  871. + rts
  872. +
  873. + .size ffi_csky_cacheflush, .-ffi_csky_cacheflush
  874. +
  875. +#endif /* __CSKYABIV2__ */