diff options
Diffstat (limited to 'meta')
| -rw-r--r-- | meta/recipes-support/libffi/libffi/0001-New-RISC-V-port-281.patch | 827 | ||||
| -rw-r--r-- | meta/recipes-support/libffi/libffi/0001-libffi-Support-musl-x32-build.patch | 30 | ||||
| -rw-r--r-- | meta/recipes-support/libffi/libffi/0001-mips-Use-compiler-internal-define-for-linux.patch | 32 | ||||
| -rw-r--r-- | meta/recipes-support/libffi/libffi/0001-mips-fix-MIPS-softfloat-build-issue.patch | 177 | ||||
| -rw-r--r-- | meta/recipes-support/libffi/libffi/not-win32.patch | 10 | ||||
| -rw-r--r-- | meta/recipes-support/libffi/libffi_3.3~rc0.bb (renamed from meta/recipes-support/libffi/libffi_3.2.1.bb) | 19 |
6 files changed, 14 insertions, 1081 deletions
diff --git a/meta/recipes-support/libffi/libffi/0001-New-RISC-V-port-281.patch b/meta/recipes-support/libffi/libffi/0001-New-RISC-V-port-281.patch deleted file mode 100644 index 589c4d3c44..0000000000 --- a/meta/recipes-support/libffi/libffi/0001-New-RISC-V-port-281.patch +++ /dev/null | |||
| @@ -1,827 +0,0 @@ | |||
| 1 | From 8ac73103bf12ce4f776940cb17f3ced15a362f23 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Stef O'Rear <sorear2@gmail.com> | ||
| 3 | Date: Sun, 11 Mar 2018 05:55:15 -0700 | ||
| 4 | Subject: [PATCH] New RISC-V port (#281) | ||
| 5 | |||
| 6 | * Add RISC-V support | ||
| 7 | |||
| 8 | This patch adds support for the RISC-V architecture (https://riscv.org). | ||
| 9 | |||
| 10 | This patch has been tested using QEMU user-mode emulation and GCC 7.2.0 | ||
| 11 | in the following configurations: | ||
| 12 | |||
| 13 | * -march=rv32imac -mabi=ilp32 | ||
| 14 | * -march=rv32g -mabi=ilp32d | ||
| 15 | * -march=rv64imac -mabi=lp64 | ||
| 16 | * -march=rv64g -mabi=lp64d | ||
| 17 | |||
| 18 | The ABI currently can be found at | ||
| 19 | https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md . | ||
| 20 | |||
| 21 | * Add RISC-V to README | ||
| 22 | |||
| 23 | * RISC-V: fix configure.host | ||
| 24 | |||
| 25 | Upstream-Status: Backport [https://github.com/libffi/libffi/commit/3840d49aaa831d649b1597518a2903dfed0d57f3] | ||
| 26 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
| 27 | --- | ||
| 28 | Makefile.am | 4 + | ||
| 29 | configure.ac | 5 + | ||
| 30 | src/riscv/ffi.c | 445 ++++++++++++++++++++++++++++++++++++++++++ | ||
| 31 | src/riscv/ffitarget.h | 68 +++++++ | ||
| 32 | src/riscv/sysv.S | 214 ++++++++++++++++++++ | ||
| 33 | 5 files changed, 736 insertions(+) | ||
| 34 | create mode 100644 src/riscv/ffi.c | ||
| 35 | create mode 100644 src/riscv/ffitarget.h | ||
| 36 | create mode 100644 src/riscv/sysv.S | ||
| 37 | |||
| 38 | diff --git a/Makefile.am b/Makefile.am | ||
| 39 | index 0e40451..3837650 100644 | ||
| 40 | --- a/Makefile.am | ||
| 41 | +++ b/Makefile.am | ||
| 42 | @@ -32,6 +32,7 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj \ | ||
| 43 | src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S \ | ||
| 44 | src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \ | ||
| 45 | src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \ | ||
| 46 | + src/riscv/ffi.c src/riscv/ffitarget.h src/riscv/sysv.S \ | ||
| 47 | src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h \ | ||
| 48 | src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h src/sh64/ffi.c \ | ||
| 49 | src/sh64/sysv.S src/sh64/ffitarget.h src/sparc/v8.S \ | ||
| 50 | @@ -122,6 +123,9 @@ endif | ||
| 51 | if MIPS | ||
| 52 | nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S | ||
| 53 | endif | ||
| 54 | +if RISCV | ||
| 55 | +nodist_libffi_la_SOURCES += src/riscv/ffi.c src/riscv/sysv.S | ||
| 56 | +endif | ||
| 57 | if BFIN | ||
| 58 | nodist_libffi_la_SOURCES += src/bfin/ffi.c src/bfin/sysv.S | ||
| 59 | endif | ||
| 60 | diff --git a/configure.ac b/configure.ac | ||
| 61 | index ce30853..33375aa 100644 | ||
| 62 | --- a/configure.ac | ||
| 63 | +++ b/configure.ac | ||
| 64 | @@ -226,6 +226,10 @@ case "$host" in | ||
| 65 | TARGET=MIPS; TARGETDIR=mips | ||
| 66 | ;; | ||
| 67 | |||
| 68 | + riscv*-*-*) | ||
| 69 | + TARGET=RISCV; TARGETDIR=riscv | ||
| 70 | + ;; | ||
| 71 | + | ||
| 72 | nios2*-linux*) | ||
| 73 | TARGET=NIOS2; TARGETDIR=nios2 | ||
| 74 | ;; | ||
| 75 | @@ -298,6 +302,7 @@ if test $TARGETDIR = unknown; then | ||
| 76 | fi | ||
| 77 | |||
| 78 | AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS) | ||
| 79 | +AM_CONDITIONAL(RISCV, test x$TARGET = xRISCV) | ||
| 80 | AM_CONDITIONAL(BFIN, test x$TARGET = xBFIN) | ||
| 81 | AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC) | ||
| 82 | AM_CONDITIONAL(X86, test x$TARGET = xX86) | ||
| 83 | diff --git a/src/riscv/ffi.c b/src/riscv/ffi.c | ||
| 84 | new file mode 100644 | ||
| 85 | index 0000000..b744fdd | ||
| 86 | --- /dev/null | ||
| 87 | +++ b/src/riscv/ffi.c | ||
| 88 | @@ -0,0 +1,445 @@ | ||
| 89 | +/* ----------------------------------------------------------------------- | ||
| 90 | + ffi.c - Copyright (c) 2015 Michael Knyszek <mknyszek@berkeley.edu> | ||
| 91 | + 2015 Andrew Waterman <waterman@cs.berkeley.edu> | ||
| 92 | + 2018 Stef O'Rear <sorear2@gmail.com> | ||
| 93 | + Based on MIPS N32/64 port | ||
| 94 | + | ||
| 95 | + RISC-V Foreign Function Interface | ||
| 96 | + | ||
| 97 | + Permission is hereby granted, free of charge, to any person obtaining | ||
| 98 | + a copy of this software and associated documentation files (the | ||
| 99 | + ``Software''), to deal in the Software without restriction, including | ||
| 100 | + without limitation the rights to use, copy, modify, merge, publish, | ||
| 101 | + distribute, sublicense, and/or sell copies of the Software, and to | ||
| 102 | + permit persons to whom the Software is furnished to do so, subject to | ||
| 103 | + the following conditions: | ||
| 104 | + | ||
| 105 | + The above copyright notice and this permission notice shall be included | ||
| 106 | + in all copies or substantial portions of the Software. | ||
| 107 | + | ||
| 108 | + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, | ||
| 109 | + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 110 | + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 111 | + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| 112 | + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
| 113 | + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 114 | + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| 115 | + DEALINGS IN THE SOFTWARE. | ||
| 116 | + ----------------------------------------------------------------------- */ | ||
| 117 | + | ||
| 118 | +#include <ffi.h> | ||
| 119 | +#include <ffi_common.h> | ||
| 120 | + | ||
| 121 | +#include <stdlib.h> | ||
| 122 | +#include <stdint.h> | ||
| 123 | + | ||
| 124 | +#if __riscv_float_abi_double | ||
| 125 | +#define ABI_FLEN 64 | ||
| 126 | +#define ABI_FLOAT double | ||
| 127 | +#elif __riscv_float_abi_single | ||
| 128 | +#define ABI_FLEN 32 | ||
| 129 | +#define ABI_FLOAT float | ||
| 130 | +#endif | ||
| 131 | + | ||
| 132 | +#define NARGREG 8 | ||
| 133 | +#define STKALIGN 16 | ||
| 134 | +#define MAXCOPYARG (2 * sizeof(double)) | ||
| 135 | + | ||
| 136 | +typedef struct call_context | ||
| 137 | +{ | ||
| 138 | +#if ABI_FLEN | ||
| 139 | + ABI_FLOAT fa[8]; | ||
| 140 | +#endif | ||
| 141 | + size_t a[8]; | ||
| 142 | + /* used by the assembly code to in-place construct its own stack frame */ | ||
| 143 | + char frame[16]; | ||
| 144 | +} call_context; | ||
| 145 | + | ||
| 146 | +typedef struct call_builder | ||
| 147 | +{ | ||
| 148 | + call_context *aregs; | ||
| 149 | + int used_integer; | ||
| 150 | + int used_float; | ||
| 151 | + size_t *used_stack; | ||
| 152 | +} call_builder; | ||
| 153 | + | ||
| 154 | +/* integer (not pointer) less than ABI XLEN */ | ||
| 155 | +/* FFI_TYPE_INT does not appear to be used */ | ||
| 156 | +#if __SIZEOF_POINTER__ == 8 | ||
| 157 | +#define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT64) | ||
| 158 | +#else | ||
| 159 | +#define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT32) | ||
| 160 | +#endif | ||
| 161 | + | ||
| 162 | +#if ABI_FLEN | ||
| 163 | +typedef struct { | ||
| 164 | + char as_elements, type1, offset2, type2; | ||
| 165 | +} float_struct_info; | ||
| 166 | + | ||
| 167 | +#if ABI_FLEN >= 64 | ||
| 168 | +#define IS_FLOAT(type) ((type) >= FFI_TYPE_FLOAT && (type) <= FFI_TYPE_DOUBLE) | ||
| 169 | +#else | ||
| 170 | +#define IS_FLOAT(type) ((type) == FFI_TYPE_FLOAT) | ||
| 171 | +#endif | ||
| 172 | + | ||
| 173 | +static ffi_type **flatten_struct(ffi_type *in, ffi_type **out, ffi_type **out_end) { | ||
| 174 | + int i; | ||
| 175 | + if (out == out_end) return out; | ||
| 176 | + if (in->type != FFI_TYPE_STRUCT) { | ||
| 177 | + *(out++) = in; | ||
| 178 | + } else { | ||
| 179 | + for (i = 0; in->elements[i]; i++) | ||
| 180 | + out = flatten_struct(in->elements[i], out, out_end); | ||
| 181 | + } | ||
| 182 | + return out; | ||
| 183 | +} | ||
| 184 | + | ||
| 185 | +/* Structs with at most two fields after flattening, one of which is of | ||
| 186 | + floating point type, are passed in multiple registers if sufficient | ||
| 187 | + registers are available. */ | ||
| 188 | +static float_struct_info struct_passed_as_elements(call_builder *cb, ffi_type *top) { | ||
| 189 | + float_struct_info ret = {0, 0, 0, 0}; | ||
| 190 | + ffi_type *fields[3]; | ||
| 191 | + int num_floats, num_ints; | ||
| 192 | + int num_fields = flatten_struct(top, fields, fields + 3) - fields; | ||
| 193 | + | ||
| 194 | + if (num_fields == 1) { | ||
| 195 | + if (IS_FLOAT(fields[0]->type)) { | ||
| 196 | + ret.as_elements = 1; | ||
| 197 | + ret.type1 = fields[0]->type; | ||
| 198 | + } | ||
| 199 | + } else if (num_fields == 2) { | ||
| 200 | + num_floats = IS_FLOAT(fields[0]->type) + IS_FLOAT(fields[1]->type); | ||
| 201 | + num_ints = IS_INT(fields[0]->type) + IS_INT(fields[1]->type); | ||
| 202 | + if (num_floats == 0 || num_floats + num_ints != 2) | ||
| 203 | + return ret; | ||
| 204 | + if (cb->used_float + num_floats > NARGREG || cb->used_integer + (2 - num_floats) > NARGREG) | ||
| 205 | + return ret; | ||
| 206 | + if (!IS_FLOAT(fields[0]->type) && !IS_FLOAT(fields[1]->type)) | ||
| 207 | + return ret; | ||
| 208 | + | ||
| 209 | + ret.type1 = fields[0]->type; | ||
| 210 | + ret.type2 = fields[1]->type; | ||
| 211 | + ret.offset2 = ALIGN(fields[0]->size, fields[1]->alignment); | ||
| 212 | + ret.as_elements = 1; | ||
| 213 | + } | ||
| 214 | + | ||
| 215 | + return ret; | ||
| 216 | +} | ||
| 217 | +#endif | ||
| 218 | + | ||
| 219 | +/* allocates a single register, float register, or XLEN-sized stack slot to a datum */ | ||
| 220 | +static void marshal_atom(call_builder *cb, int type, void *data) { | ||
| 221 | + size_t value = 0; | ||
| 222 | + switch (type) { | ||
| 223 | + case FFI_TYPE_UINT8: value = *(uint8_t *)data; break; | ||
| 224 | + case FFI_TYPE_SINT8: value = *(int8_t *)data; break; | ||
| 225 | + case FFI_TYPE_UINT16: value = *(uint16_t *)data; break; | ||
| 226 | + case FFI_TYPE_SINT16: value = *(int16_t *)data; break; | ||
| 227 | + /* 32-bit quantities are always sign-extended in the ABI */ | ||
| 228 | + case FFI_TYPE_UINT32: value = *(int32_t *)data; break; | ||
| 229 | + case FFI_TYPE_SINT32: value = *(int32_t *)data; break; | ||
| 230 | +#if __SIZEOF_POINTER__ == 8 | ||
| 231 | + case FFI_TYPE_UINT64: value = *(uint64_t *)data; break; | ||
| 232 | + case FFI_TYPE_SINT64: value = *(int64_t *)data; break; | ||
| 233 | +#endif | ||
| 234 | + case FFI_TYPE_POINTER: value = *(size_t *)data; break; | ||
| 235 | + | ||
| 236 | + /* float values may be recoded in an implementation-defined way | ||
| 237 | + by hardware conforming to 2.1 or earlier, so use asm to | ||
| 238 | + reinterpret floats as doubles */ | ||
| 239 | +#if ABI_FLEN >= 32 | ||
| 240 | + case FFI_TYPE_FLOAT: | ||
| 241 | + asm("" : "=f"(cb->aregs->fa[cb->used_float++]) : "0"(*(float *)data)); | ||
| 242 | + return; | ||
| 243 | +#endif | ||
| 244 | +#if ABI_FLEN >= 64 | ||
| 245 | + case FFI_TYPE_DOUBLE: | ||
| 246 | + asm("" : "=f"(cb->aregs->fa[cb->used_float++]) : "0"(*(double *)data)); | ||
| 247 | + return; | ||
| 248 | +#endif | ||
| 249 | + default: FFI_ASSERT(0); break; | ||
| 250 | + } | ||
| 251 | + | ||
| 252 | + if (cb->used_integer == NARGREG) { | ||
| 253 | + *cb->used_stack++ = value; | ||
| 254 | + } else { | ||
| 255 | + cb->aregs->a[cb->used_integer++] = value; | ||
| 256 | + } | ||
| 257 | +} | ||
| 258 | + | ||
| 259 | +static void unmarshal_atom(call_builder *cb, int type, void *data) { | ||
| 260 | + size_t value; | ||
| 261 | + switch (type) { | ||
| 262 | +#if ABI_FLEN >= 32 | ||
| 263 | + case FFI_TYPE_FLOAT: | ||
| 264 | + asm("" : "=f"(*(float *)data) : "0"(cb->aregs->fa[cb->used_float++])); | ||
| 265 | + return; | ||
| 266 | +#endif | ||
| 267 | +#if ABI_FLEN >= 64 | ||
| 268 | + case FFI_TYPE_DOUBLE: | ||
| 269 | + asm("" : "=f"(*(double *)data) : "0"(cb->aregs->fa[cb->used_float++])); | ||
| 270 | + return; | ||
| 271 | +#endif | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + if (cb->used_integer == NARGREG) { | ||
| 275 | + value = *cb->used_stack++; | ||
| 276 | + } else { | ||
| 277 | + value = cb->aregs->a[cb->used_integer++]; | ||
| 278 | + } | ||
| 279 | + | ||
| 280 | + switch (type) { | ||
| 281 | + case FFI_TYPE_UINT8: *(uint8_t *)data = value; break; | ||
| 282 | + case FFI_TYPE_SINT8: *(uint8_t *)data = value; break; | ||
| 283 | + case FFI_TYPE_UINT16: *(uint16_t *)data = value; break; | ||
| 284 | + case FFI_TYPE_SINT16: *(uint16_t *)data = value; break; | ||
| 285 | + case FFI_TYPE_UINT32: *(uint32_t *)data = value; break; | ||
| 286 | + case FFI_TYPE_SINT32: *(uint32_t *)data = value; break; | ||
| 287 | +#if __SIZEOF_POINTER__ == 8 | ||
| 288 | + case FFI_TYPE_UINT64: *(uint64_t *)data = value; break; | ||
| 289 | + case FFI_TYPE_SINT64: *(uint64_t *)data = value; break; | ||
| 290 | +#endif | ||
| 291 | + case FFI_TYPE_POINTER: *(size_t *)data = value; break; | ||
| 292 | + default: FFI_ASSERT(0); break; | ||
| 293 | + } | ||
| 294 | +} | ||
| 295 | + | ||
| 296 | +/* adds an argument to a call, or a not by reference return value */ | ||
| 297 | +static void marshal(call_builder *cb, ffi_type *type, int var, void *data) { | ||
| 298 | + size_t realign[2]; | ||
| 299 | + | ||
| 300 | +#if ABI_FLEN | ||
| 301 | + if (!var && type->type == FFI_TYPE_STRUCT) { | ||
| 302 | + float_struct_info fsi = struct_passed_as_elements(cb, type); | ||
| 303 | + if (fsi.as_elements) { | ||
| 304 | + marshal_atom(cb, fsi.type1, data); | ||
| 305 | + if (fsi.offset2) | ||
| 306 | + marshal_atom(cb, fsi.type2, ((char*)data) + fsi.offset2); | ||
| 307 | + return; | ||
| 308 | + } | ||
| 309 | + } | ||
| 310 | + | ||
| 311 | + if (!var && cb->used_float < NARGREG && IS_FLOAT(type->type)) { | ||
| 312 | + marshal_atom(cb, type->type, data); | ||
| 313 | + return; | ||
| 314 | + } | ||
| 315 | +#endif | ||
| 316 | + | ||
| 317 | + if (type->size > 2 * __SIZEOF_POINTER__) { | ||
| 318 | + /* pass by reference */ | ||
| 319 | + marshal_atom(cb, FFI_TYPE_POINTER, &data); | ||
| 320 | + } else if (IS_INT(type->type) || type->type == FFI_TYPE_POINTER) { | ||
| 321 | + marshal_atom(cb, type->type, data); | ||
| 322 | + } else { | ||
| 323 | + /* overlong integers, soft-float floats, and structs without special | ||
| 324 | + float handling are treated identically from this point on */ | ||
| 325 | + | ||
| 326 | + /* variadics are aligned even in registers */ | ||
| 327 | + if (type->alignment > __SIZEOF_POINTER__) { | ||
| 328 | + if (var) | ||
| 329 | + cb->used_integer = ALIGN(cb->used_integer, 2); | ||
| 330 | + cb->used_stack = (size_t *)ALIGN(cb->used_stack, 2*__SIZEOF_POINTER__); | ||
| 331 | + } | ||
| 332 | + | ||
| 333 | + memcpy(realign, data, type->size); | ||
| 334 | + if (type->size > 0) | ||
| 335 | + marshal_atom(cb, FFI_TYPE_POINTER, realign); | ||
| 336 | + if (type->size > __SIZEOF_POINTER__) | ||
| 337 | + marshal_atom(cb, FFI_TYPE_POINTER, realign + 1); | ||
| 338 | + } | ||
| 339 | +} | ||
| 340 | + | ||
| 341 | +/* for arguments passed by reference returns the pointer, otherwise the arg is copied (up to MAXCOPYARG bytes) */ | ||
| 342 | +static void *unmarshal(call_builder *cb, ffi_type *type, int var, void *data) { | ||
| 343 | + size_t realign[2]; | ||
| 344 | + void *pointer; | ||
| 345 | + | ||
| 346 | +#if ABI_FLEN | ||
| 347 | + if (!var && type->type == FFI_TYPE_STRUCT) { | ||
| 348 | + float_struct_info fsi = struct_passed_as_elements(cb, type); | ||
| 349 | + if (fsi.as_elements) { | ||
| 350 | + unmarshal_atom(cb, fsi.type1, data); | ||
| 351 | + if (fsi.offset2) | ||
| 352 | + unmarshal_atom(cb, fsi.type2, ((char*)data) + fsi.offset2); | ||
| 353 | + return data; | ||
| 354 | + } | ||
| 355 | + } | ||
| 356 | + | ||
| 357 | + if (!var && cb->used_float < NARGREG && IS_FLOAT(type->type)) { | ||
| 358 | + unmarshal_atom(cb, type->type, data); | ||
| 359 | + return data; | ||
| 360 | + } | ||
| 361 | +#endif | ||
| 362 | + | ||
| 363 | + if (type->size > 2 * __SIZEOF_POINTER__) { | ||
| 364 | + /* pass by reference */ | ||
| 365 | + unmarshal_atom(cb, FFI_TYPE_POINTER, (char*)&pointer); | ||
| 366 | + return pointer; | ||
| 367 | + } else if (IS_INT(type->type) || type->type == FFI_TYPE_POINTER) { | ||
| 368 | + unmarshal_atom(cb, type->type, data); | ||
| 369 | + return data; | ||
| 370 | + } else { | ||
| 371 | + /* overlong integers, soft-float floats, and structs without special | ||
| 372 | + float handling are treated identically from this point on */ | ||
| 373 | + | ||
| 374 | + /* variadics are aligned even in registers */ | ||
| 375 | + if (type->alignment > __SIZEOF_POINTER__) { | ||
| 376 | + if (var) | ||
| 377 | + cb->used_integer = ALIGN(cb->used_integer, 2); | ||
| 378 | + cb->used_stack = (size_t *)ALIGN(cb->used_stack, 2*__SIZEOF_POINTER__); | ||
| 379 | + } | ||
| 380 | + | ||
| 381 | + if (type->size > 0) | ||
| 382 | + unmarshal_atom(cb, FFI_TYPE_POINTER, realign); | ||
| 383 | + if (type->size > __SIZEOF_POINTER__) | ||
| 384 | + unmarshal_atom(cb, FFI_TYPE_POINTER, realign + 1); | ||
| 385 | + memcpy(data, realign, type->size); | ||
| 386 | + return data; | ||
| 387 | + } | ||
| 388 | +} | ||
| 389 | + | ||
| 390 | +static int passed_by_ref(call_builder *cb, ffi_type *type, int var) { | ||
| 391 | +#if ABI_FLEN | ||
| 392 | + if (!var && type->type == FFI_TYPE_STRUCT) { | ||
| 393 | + float_struct_info fsi = struct_passed_as_elements(cb, type); | ||
| 394 | + if (fsi.as_elements) return 0; | ||
| 395 | + } | ||
| 396 | +#endif | ||
| 397 | + | ||
| 398 | + return type->size > 2 * __SIZEOF_POINTER__; | ||
| 399 | +} | ||
| 400 | + | ||
| 401 | +/* Perform machine dependent cif processing */ | ||
| 402 | +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { | ||
| 403 | + cif->riscv_nfixedargs = cif->nargs; | ||
| 404 | + return FFI_OK; | ||
| 405 | +} | ||
| 406 | + | ||
| 407 | +/* Perform machine dependent cif processing when we have a variadic function */ | ||
| 408 | + | ||
| 409 | +ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs, unsigned int ntotalargs) { | ||
| 410 | + cif->riscv_nfixedargs = nfixedargs; | ||
| 411 | + return FFI_OK; | ||
| 412 | +} | ||
| 413 | + | ||
| 414 | +/* Low level routine for calling functions */ | ||
| 415 | +extern void ffi_call_asm(void *stack, struct call_context *regs, void (*fn)(void)) FFI_HIDDEN; | ||
| 416 | + | ||
| 417 | +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) | ||
| 418 | +{ | ||
| 419 | + /* this is a conservative estimate, assuming a complex return value and | ||
| 420 | + that all remaining arguments are long long / __int128 */ | ||
| 421 | + size_t arg_bytes = cif->nargs <= 3 ? 0 : | ||
| 422 | + ALIGN(2 * sizeof(size_t) * (cif->nargs - 3), STKALIGN); | ||
| 423 | + size_t rval_bytes = 0; | ||
| 424 | + if (rvalue == NULL && cif->rtype->size > 2*__SIZEOF_POINTER__) | ||
| 425 | + rval_bytes = ALIGN(cif->rtype->size, STKALIGN); | ||
| 426 | + size_t alloc_size = arg_bytes + rval_bytes + sizeof(call_context); | ||
| 427 | + | ||
| 428 | + /* the assembly code will deallocate all stack data at lower addresses | ||
| 429 | + than the argument region, so we need to allocate the frame and the | ||
| 430 | + return value after the arguments in a single allocation */ | ||
| 431 | + size_t alloc_base; | ||
| 432 | + /* Argument region must be 16-byte aligned */ | ||
| 433 | + if (_Alignof(max_align_t) >= STKALIGN) { | ||
| 434 | + /* since sizeof long double is normally 16, the compiler will | ||
| 435 | + guarantee alloca alignment to at least that much */ | ||
| 436 | + alloc_base = (size_t)alloca(alloc_size); | ||
| 437 | + } else { | ||
| 438 | + alloc_base = ALIGN(alloca(alloc_size + STKALIGN - 1), STKALIGN); | ||
| 439 | + } | ||
| 440 | + | ||
| 441 | + if (rval_bytes) | ||
| 442 | + rvalue = (void*)(alloc_base + arg_bytes); | ||
| 443 | + | ||
| 444 | + call_builder cb; | ||
| 445 | + cb.used_float = cb.used_integer = 0; | ||
| 446 | + cb.aregs = (call_context*)(alloc_base + arg_bytes + rval_bytes); | ||
| 447 | + cb.used_stack = (void*)alloc_base; | ||
| 448 | + | ||
| 449 | + int return_by_ref = passed_by_ref(&cb, cif->rtype, 0); | ||
| 450 | + if (return_by_ref) | ||
| 451 | + marshal(&cb, &ffi_type_pointer, 0, &rvalue); | ||
| 452 | + | ||
| 453 | + int i; | ||
| 454 | + for (i = 0; i < cif->nargs; i++) | ||
| 455 | + marshal(&cb, cif->arg_types[i], i >= cif->riscv_nfixedargs, avalue[i]); | ||
| 456 | + | ||
| 457 | + ffi_call_asm((void*)alloc_base, cb.aregs, fn); | ||
| 458 | + | ||
| 459 | + cb.used_float = cb.used_integer = 0; | ||
| 460 | + if (!return_by_ref && rvalue) | ||
| 461 | + unmarshal(&cb, cif->rtype, 0, rvalue); | ||
| 462 | +} | ||
| 463 | + | ||
| 464 | +extern void ffi_closure_asm(void) FFI_HIDDEN; | ||
| 465 | + | ||
| 466 | +ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void (*fun)(ffi_cif*,void*,void**,void*), void *user_data, void *codeloc) | ||
| 467 | +{ | ||
| 468 | + uint32_t *tramp = (uint32_t *) &closure->tramp[0]; | ||
| 469 | + uint64_t fn = (uint64_t) (uintptr_t) ffi_closure_asm; | ||
| 470 | + | ||
| 471 | + if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI) | ||
| 472 | + return FFI_BAD_ABI; | ||
| 473 | + | ||
| 474 | + /* we will call ffi_closure_inner with codeloc, not closure, but as long | ||
| 475 | + as the memory is readable it should work */ | ||
| 476 | + | ||
| 477 | + tramp[0] = 0x00000317; /* auipc t1, 0 (i.e. t0 <- codeloc) */ | ||
| 478 | +#if __SIZEOF_POINTER__ == 8 | ||
| 479 | + tramp[1] = 0x01033383; /* ld t2, 16(t1) */ | ||
| 480 | +#else | ||
| 481 | + tramp[1] = 0x01032383; /* lw t2, 16(t1) */ | ||
| 482 | +#endif | ||
| 483 | + tramp[2] = 0x00038067; /* jr t2 */ | ||
| 484 | + tramp[3] = 0x00000013; /* nop */ | ||
| 485 | + tramp[4] = fn; | ||
| 486 | + tramp[5] = fn >> 32; | ||
| 487 | + | ||
| 488 | + closure->cif = cif; | ||
| 489 | + closure->fun = fun; | ||
| 490 | + closure->user_data = user_data; | ||
| 491 | + | ||
| 492 | + __builtin___clear_cache(codeloc, codeloc + FFI_TRAMPOLINE_SIZE); | ||
| 493 | + | ||
| 494 | + return FFI_OK; | ||
| 495 | +} | ||
| 496 | + | ||
| 497 | +/* Called by the assembly code with aregs pointing to saved argument registers | ||
| 498 | + and stack pointing to the stacked arguments. Return values passed in | ||
| 499 | + registers will be reloaded from aregs. */ | ||
| 500 | +void FFI_HIDDEN ffi_closure_inner(size_t *stack, call_context *aregs, ffi_closure *closure) { | ||
| 501 | + ffi_cif *cif = closure->cif; | ||
| 502 | + void **avalue = alloca(cif->nargs * sizeof(void*)); | ||
| 503 | + /* storage for arguments which will be copied by unmarshal(). We could | ||
| 504 | + theoretically avoid the copies in many cases and use at most 128 bytes | ||
| 505 | + of memory, but allocating disjoint storage for each argument is | ||
| 506 | + simpler. */ | ||
| 507 | + char *astorage = alloca(cif->nargs * MAXCOPYARG); | ||
| 508 | + void *rvalue; | ||
| 509 | + call_builder cb; | ||
| 510 | + int return_by_ref; | ||
| 511 | + int i; | ||
| 512 | + | ||
| 513 | + cb.aregs = aregs; | ||
| 514 | + cb.used_integer = cb.used_float = 0; | ||
| 515 | + cb.used_stack = stack; | ||
| 516 | + | ||
| 517 | + return_by_ref = passed_by_ref(&cb, cif->rtype, 0); | ||
| 518 | + if (return_by_ref) | ||
| 519 | + unmarshal(&cb, &ffi_type_pointer, 0, &rvalue); | ||
| 520 | + else | ||
| 521 | + rvalue = alloca(cif->rtype->size); | ||
| 522 | + | ||
| 523 | + for (i = 0; i < cif->nargs; i++) | ||
| 524 | + avalue[i] = unmarshal(&cb, cif->arg_types[i], | ||
| 525 | + i >= cif->riscv_nfixedargs, astorage + i*MAXCOPYARG); | ||
| 526 | + | ||
| 527 | + (closure->fun)(cif, rvalue, avalue, closure->user_data); | ||
| 528 | + | ||
| 529 | + if (!return_by_ref && cif->rtype->type != FFI_TYPE_VOID) { | ||
| 530 | + cb.used_integer = cb.used_float = 0; | ||
| 531 | + marshal(&cb, cif->rtype, 0, rvalue); | ||
| 532 | + } | ||
| 533 | +} | ||
| 534 | diff --git a/src/riscv/ffitarget.h b/src/riscv/ffitarget.h | ||
| 535 | new file mode 100644 | ||
| 536 | index 0000000..fcaa899 | ||
| 537 | --- /dev/null | ||
| 538 | +++ b/src/riscv/ffitarget.h | ||
| 539 | @@ -0,0 +1,68 @@ | ||
| 540 | +/* -----------------------------------------------------------------*-C-*- | ||
| 541 | + ffitarget.h - 2014 Michael Knyszek | ||
| 542 | + | ||
| 543 | + Target configuration macros for RISC-V. | ||
| 544 | + | ||
| 545 | + Permission is hereby granted, free of charge, to any person obtaining | ||
| 546 | + a copy of this software and associated documentation files (the | ||
| 547 | + ``Software''), to deal in the Software without restriction, including | ||
| 548 | + without limitation the rights to use, copy, modify, merge, publish, | ||
| 549 | + distribute, sublicense, and/or sell copies of the Software, and to | ||
| 550 | + permit persons to whom the Software is furnished to do so, subject to | ||
| 551 | + the following conditions: | ||
| 552 | + | ||
| 553 | + The above copyright notice and this permission notice shall be included | ||
| 554 | + in all copies or substantial portions of the Software. | ||
| 555 | + | ||
| 556 | + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, | ||
| 557 | + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 558 | + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 559 | + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| 560 | + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
| 561 | + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 562 | + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| 563 | + DEALINGS IN THE SOFTWARE. | ||
| 564 | + | ||
| 565 | + ----------------------------------------------------------------------- */ | ||
| 566 | + | ||
| 567 | +#ifndef LIBFFI_TARGET_H | ||
| 568 | +#define LIBFFI_TARGET_H | ||
| 569 | + | ||
| 570 | +#ifndef LIBFFI_H | ||
| 571 | +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." | ||
| 572 | +#endif | ||
| 573 | + | ||
| 574 | +#ifndef __riscv | ||
| 575 | +#error "libffi was configured for a RISC-V target but this does not appear to be a RISC-V compiler." | ||
| 576 | +#endif | ||
| 577 | + | ||
| 578 | +#ifndef LIBFFI_ASM | ||
| 579 | + | ||
| 580 | +typedef unsigned long ffi_arg; | ||
| 581 | +typedef signed long ffi_sarg; | ||
| 582 | + | ||
| 583 | +/* FFI_UNUSED_NN and riscv_unused are to maintain ABI compatibility with a | ||
| 584 | + distributed Berkeley patch from 2014, and can be removed at SONAME bump */ | ||
| 585 | +typedef enum ffi_abi { | ||
| 586 | + FFI_FIRST_ABI = 0, | ||
| 587 | + FFI_SYSV, | ||
| 588 | + FFI_UNUSED_1, | ||
| 589 | + FFI_UNUSED_2, | ||
| 590 | + FFI_UNUSED_3, | ||
| 591 | + FFI_LAST_ABI, | ||
| 592 | + | ||
| 593 | + FFI_DEFAULT_ABI = FFI_SYSV | ||
| 594 | +} ffi_abi; | ||
| 595 | + | ||
| 596 | +#endif /* LIBFFI_ASM */ | ||
| 597 | + | ||
| 598 | +/* ---- Definitions for closures ----------------------------------------- */ | ||
| 599 | + | ||
| 600 | +#define FFI_CLOSURES 1 | ||
| 601 | +#define FFI_TRAMPOLINE_SIZE 24 | ||
| 602 | +#define FFI_NATIVE_RAW_API 0 | ||
| 603 | +#define FFI_EXTRA_CIF_FIELDS unsigned riscv_nfixedargs; unsigned riscv_unused; | ||
| 604 | +#define FFI_TARGET_SPECIFIC_VARIADIC | ||
| 605 | + | ||
| 606 | +#endif | ||
| 607 | + | ||
| 608 | diff --git a/src/riscv/sysv.S b/src/riscv/sysv.S | ||
| 609 | new file mode 100644 | ||
| 610 | index 0000000..2d09865 | ||
| 611 | --- /dev/null | ||
| 612 | +++ b/src/riscv/sysv.S | ||
| 613 | @@ -0,0 +1,214 @@ | ||
| 614 | +/* ----------------------------------------------------------------------- | ||
| 615 | + ffi.c - Copyright (c) 2015 Michael Knyszek <mknyszek@berkeley.edu> | ||
| 616 | + 2015 Andrew Waterman <waterman@cs.berkeley.edu> | ||
| 617 | + 2018 Stef O'Rear <sorear2@gmail.com> | ||
| 618 | + | ||
| 619 | + RISC-V Foreign Function Interface | ||
| 620 | + | ||
| 621 | + Permission is hereby granted, free of charge, to any person obtaining | ||
| 622 | + a copy of this software and associated documentation files (the | ||
| 623 | + ``Software''), to deal in the Software without restriction, including | ||
| 624 | + without limitation the rights to use, copy, modify, merge, publish, | ||
| 625 | + distribute, sublicense, and/or sell copies of the Software, and to | ||
| 626 | + permit persons to whom the Software is furnished to do so, subject to | ||
| 627 | + the following conditions: | ||
| 628 | + | ||
| 629 | + The above copyright notice and this permission notice shall be included | ||
| 630 | + in all copies or substantial portions of the Software. | ||
| 631 | + | ||
| 632 | + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, | ||
| 633 | + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 634 | + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 635 | + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| 636 | + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
| 637 | + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 638 | + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| 639 | + DEALINGS IN THE SOFTWARE. | ||
| 640 | + ----------------------------------------------------------------------- */ | ||
| 641 | + | ||
| 642 | +#define LIBFFI_ASM | ||
| 643 | +#include <fficonfig.h> | ||
| 644 | +#include <ffi.h> | ||
| 645 | + | ||
| 646 | +/* Define aliases so that we can handle all ABIs uniformly */ | ||
| 647 | + | ||
| 648 | +#if __SIZEOF_POINTER__ == 8 | ||
| 649 | +#define PTRS 8 | ||
| 650 | +#define LARG ld | ||
| 651 | +#define SARG sd | ||
| 652 | +#else | ||
| 653 | +#define PTRS 4 | ||
| 654 | +#define LARG lw | ||
| 655 | +#define SARG sw | ||
| 656 | +#endif | ||
| 657 | + | ||
| 658 | +#if __riscv_float_abi_double | ||
| 659 | +#define FLTS 8 | ||
| 660 | +#define FLARG fld | ||
| 661 | +#define FSARG fsd | ||
| 662 | +#elif __riscv_float_abi_single | ||
| 663 | +#define FLTS 4 | ||
| 664 | +#define FLARG flw | ||
| 665 | +#define FSARG fsw | ||
| 666 | +#else | ||
| 667 | +#define FLTS 0 | ||
| 668 | +#endif | ||
| 669 | + | ||
| 670 | +#define fp s0 | ||
| 671 | + | ||
| 672 | + .text | ||
| 673 | + .globl ffi_call_asm | ||
| 674 | + .type ffi_call_asm, @function | ||
| 675 | + .hidden ffi_call_asm | ||
| 676 | +/* | ||
| 677 | + struct call_context { | ||
| 678 | + floatreg fa[8]; | ||
| 679 | + intreg a[8]; | ||
| 680 | + intreg pad[rv32 ? 2 : 0]; | ||
| 681 | + intreg save_fp, save_ra; | ||
| 682 | + } | ||
| 683 | + void ffi_call_asm(size_t *stackargs, struct call_context *regargs, | ||
| 684 | + void (*fn)(void)); | ||
| 685 | +*/ | ||
| 686 | + | ||
| 687 | +#define FRAME_LEN (8 * FLTS + 8 * PTRS + 16) | ||
| 688 | + | ||
| 689 | +ffi_call_asm: | ||
| 690 | + .cfi_startproc | ||
| 691 | + | ||
| 692 | + /* | ||
| 693 | + We are NOT going to set up an ordinary stack frame. In order to pass | ||
| 694 | + the stacked args to the called function, we adjust our stack pointer to | ||
| 695 | + a0, which is in the _caller's_ alloca area. We establish our own stack | ||
| 696 | + frame at the end of the call_context. | ||
| 697 | + | ||
| 698 | + Anything below the arguments will be freed at this point, although we | ||
| 699 | + preserve the call_context so that it can be read back in the caller. | ||
| 700 | + */ | ||
| 701 | + | ||
| 702 | + .cfi_def_cfa 11, FRAME_LEN # interim CFA based on a1 | ||
| 703 | + SARG fp, FRAME_LEN - 2*PTRS(a1) | ||
| 704 | + .cfi_offset 8, -2*PTRS | ||
| 705 | + SARG ra, FRAME_LEN - 1*PTRS(a1) | ||
| 706 | + .cfi_offset 1, -1*PTRS | ||
| 707 | + | ||
| 708 | + addi fp, a1, FRAME_LEN | ||
| 709 | + mv sp, a0 | ||
| 710 | + .cfi_def_cfa 8, 0 # our frame is fully set up | ||
| 711 | + | ||
| 712 | + # Load arguments | ||
| 713 | + mv t1, a2 | ||
| 714 | + | ||
| 715 | +#if FLTS | ||
| 716 | + FLARG fa0, -FRAME_LEN+0*FLTS(fp) | ||
| 717 | + FLARG fa1, -FRAME_LEN+1*FLTS(fp) | ||
| 718 | + FLARG fa2, -FRAME_LEN+2*FLTS(fp) | ||
| 719 | + FLARG fa3, -FRAME_LEN+3*FLTS(fp) | ||
| 720 | + FLARG fa4, -FRAME_LEN+4*FLTS(fp) | ||
| 721 | + FLARG fa5, -FRAME_LEN+5*FLTS(fp) | ||
| 722 | + FLARG fa6, -FRAME_LEN+6*FLTS(fp) | ||
| 723 | + FLARG fa7, -FRAME_LEN+7*FLTS(fp) | ||
| 724 | +#endif | ||
| 725 | + | ||
| 726 | + LARG a0, -FRAME_LEN+8*FLTS+0*PTRS(fp) | ||
| 727 | + LARG a1, -FRAME_LEN+8*FLTS+1*PTRS(fp) | ||
| 728 | + LARG a2, -FRAME_LEN+8*FLTS+2*PTRS(fp) | ||
| 729 | + LARG a3, -FRAME_LEN+8*FLTS+3*PTRS(fp) | ||
| 730 | + LARG a4, -FRAME_LEN+8*FLTS+4*PTRS(fp) | ||
| 731 | + LARG a5, -FRAME_LEN+8*FLTS+5*PTRS(fp) | ||
| 732 | + LARG a6, -FRAME_LEN+8*FLTS+6*PTRS(fp) | ||
| 733 | + LARG a7, -FRAME_LEN+8*FLTS+7*PTRS(fp) | ||
| 734 | + | ||
| 735 | + /* Call */ | ||
| 736 | + jalr t1 | ||
| 737 | + | ||
| 738 | + /* Save return values - only a0/a1 (fa0/fa1) are used */ | ||
| 739 | +#if FLTS | ||
| 740 | + FSARG fa0, -FRAME_LEN+0*FLTS(fp) | ||
| 741 | + FSARG fa1, -FRAME_LEN+1*FLTS(fp) | ||
| 742 | +#endif | ||
| 743 | + | ||
| 744 | + SARG a0, -FRAME_LEN+8*FLTS+0*PTRS(fp) | ||
| 745 | + SARG a1, -FRAME_LEN+8*FLTS+1*PTRS(fp) | ||
| 746 | + | ||
| 747 | + /* Restore and return */ | ||
| 748 | + addi sp, fp, -FRAME_LEN | ||
| 749 | + .cfi_def_cfa 2, FRAME_LEN | ||
| 750 | + LARG ra, -1*PTRS(fp) | ||
| 751 | + .cfi_restore 1 | ||
| 752 | + LARG fp, -2*PTRS(fp) | ||
| 753 | + .cfi_restore 8 | ||
| 754 | + ret | ||
| 755 | + .cfi_endproc | ||
| 756 | + .size ffi_call_asm, .-ffi_call_asm | ||
| 757 | + | ||
| 758 | + | ||
| 759 | +/* | ||
| 760 | + ffi_closure_asm. Expects address of the passed-in ffi_closure in t1. | ||
| 761 | + void ffi_closure_inner(size_t *stackargs, struct call_context *regargs, | ||
| 762 | + ffi_closure *closure); | ||
| 763 | +*/ | ||
| 764 | + | ||
| 765 | + .globl ffi_closure_asm | ||
| 766 | + .hidden ffi_closure_asm | ||
| 767 | + .type ffi_closure_asm, @function | ||
| 768 | +ffi_closure_asm: | ||
| 769 | + .cfi_startproc | ||
| 770 | + | ||
| 771 | + addi sp, sp, -FRAME_LEN | ||
| 772 | + .cfi_def_cfa_offset FRAME_LEN | ||
| 773 | + | ||
| 774 | + /* make a frame */ | ||
| 775 | + SARG fp, FRAME_LEN - 2*PTRS(sp) | ||
| 776 | + .cfi_offset 8, -2*PTRS | ||
| 777 | + SARG ra, FRAME_LEN - 1*PTRS(sp) | ||
| 778 | + .cfi_offset 1, -1*PTRS | ||
| 779 | + addi fp, sp, FRAME_LEN | ||
| 780 | + | ||
| 781 | + /* save arguments */ | ||
| 782 | +#if FLTS | ||
| 783 | + FSARG fa0, 0*FLTS(sp) | ||
| 784 | + FSARG fa1, 1*FLTS(sp) | ||
| 785 | + FSARG fa2, 2*FLTS(sp) | ||
| 786 | + FSARG fa3, 3*FLTS(sp) | ||
| 787 | + FSARG fa4, 4*FLTS(sp) | ||
| 788 | + FSARG fa5, 5*FLTS(sp) | ||
| 789 | + FSARG fa6, 6*FLTS(sp) | ||
| 790 | + FSARG fa7, 7*FLTS(sp) | ||
| 791 | +#endif | ||
| 792 | + | ||
| 793 | + SARG a0, 8*FLTS+0*PTRS(sp) | ||
| 794 | + SARG a1, 8*FLTS+1*PTRS(sp) | ||
| 795 | + SARG a2, 8*FLTS+2*PTRS(sp) | ||
| 796 | + SARG a3, 8*FLTS+3*PTRS(sp) | ||
| 797 | + SARG a4, 8*FLTS+4*PTRS(sp) | ||
| 798 | + SARG a5, 8*FLTS+5*PTRS(sp) | ||
| 799 | + SARG a6, 8*FLTS+6*PTRS(sp) | ||
| 800 | + SARG a7, 8*FLTS+7*PTRS(sp) | ||
| 801 | + | ||
| 802 | + /* enter C */ | ||
| 803 | + addi a0, sp, FRAME_LEN | ||
| 804 | + mv a1, sp | ||
| 805 | + mv a2, t1 | ||
| 806 | + | ||
| 807 | + call ffi_closure_inner | ||
| 808 | + | ||
| 809 | + /* return values */ | ||
| 810 | +#if FLTS | ||
| 811 | + FLARG fa0, 0*FLTS(sp) | ||
| 812 | + FLARG fa1, 1*FLTS(sp) | ||
| 813 | +#endif | ||
| 814 | + | ||
| 815 | + LARG a0, 8*FLTS+0*PTRS(sp) | ||
| 816 | + LARG a1, 8*FLTS+1*PTRS(sp) | ||
| 817 | + | ||
| 818 | + /* restore and return */ | ||
| 819 | + LARG ra, FRAME_LEN-1*PTRS(sp) | ||
| 820 | + .cfi_restore 1 | ||
| 821 | + LARG fp, FRAME_LEN-2*PTRS(sp) | ||
| 822 | + .cfi_restore 8 | ||
| 823 | + addi sp, sp, FRAME_LEN | ||
| 824 | + .cfi_def_cfa_offset 0 | ||
| 825 | + ret | ||
| 826 | + .cfi_endproc | ||
| 827 | + .size ffi_closure_asm, .-ffi_closure_asm | ||
diff --git a/meta/recipes-support/libffi/libffi/0001-libffi-Support-musl-x32-build.patch b/meta/recipes-support/libffi/libffi/0001-libffi-Support-musl-x32-build.patch deleted file mode 100644 index 6b167c8421..0000000000 --- a/meta/recipes-support/libffi/libffi/0001-libffi-Support-musl-x32-build.patch +++ /dev/null | |||
| @@ -1,30 +0,0 @@ | |||
| 1 | From 69c3906c85c791716bf650aa36d9361d22acf3fb Mon Sep 17 00:00:00 2001 | ||
| 2 | From: sweeaun <swee.aun.khor@intel.com> | ||
| 3 | Date: Thu, 6 Jul 2017 16:32:46 -0700 | ||
| 4 | Subject: [PATCH] libffi: Support musl x32 build | ||
| 5 | |||
| 6 | Support libffi build with target musl-x32. | ||
| 7 | |||
| 8 | Upstream-Status: Pending | ||
| 9 | |||
| 10 | Signed-off-by: sweeaun <swee.aun.khor@intel.com> | ||
| 11 | --- | ||
| 12 | configure.ac | 2 +- | ||
| 13 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
| 14 | |||
| 15 | diff --git a/configure.ac b/configure.ac | ||
| 16 | index a7bf5ee..8ebe99c 100644 | ||
| 17 | --- a/configure.ac | ||
| 18 | +++ b/configure.ac | ||
| 19 | @@ -177,7 +177,7 @@ case "$host" in | ||
| 20 | TARGETDIR=x86 | ||
| 21 | if test $ac_cv_sizeof_size_t = 4; then | ||
| 22 | case "$host" in | ||
| 23 | - *-gnux32) | ||
| 24 | + *-gnux32 | *-muslx32) | ||
| 25 | TARGET=X86_64 | ||
| 26 | ;; | ||
| 27 | *) | ||
| 28 | -- | ||
| 29 | 2.7.4 | ||
| 30 | |||
diff --git a/meta/recipes-support/libffi/libffi/0001-mips-Use-compiler-internal-define-for-linux.patch b/meta/recipes-support/libffi/libffi/0001-mips-Use-compiler-internal-define-for-linux.patch deleted file mode 100644 index db96e63547..0000000000 --- a/meta/recipes-support/libffi/libffi/0001-mips-Use-compiler-internal-define-for-linux.patch +++ /dev/null | |||
| @@ -1,32 +0,0 @@ | |||
| 1 | From a5efaa96fd934eb245c234a5275fcf62698ef986 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Khem Raj <raj.khem@gmail.com> | ||
| 3 | Date: Thu, 2 Apr 2015 21:38:03 -0700 | ||
| 4 | Subject: [PATCH] mips: Use compiler internal define for linux | ||
| 5 | |||
| 6 | __linux__ is defined by compiler when building for | ||
| 7 | linux platforms, lets use it | ||
| 8 | |||
| 9 | |||
| 10 | Upstream-Status: Pending | ||
| 11 | |||
| 12 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
| 13 | --- | ||
| 14 | src/mips/ffitarget.h | 2 +- | ||
| 15 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
| 16 | |||
| 17 | diff --git a/src/mips/ffitarget.h b/src/mips/ffitarget.h | ||
| 18 | index 717d659..6faa358 100644 | ||
| 19 | --- a/src/mips/ffitarget.h | ||
| 20 | +++ b/src/mips/ffitarget.h | ||
| 21 | @@ -32,7 +32,7 @@ | ||
| 22 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." | ||
| 23 | #endif | ||
| 24 | |||
| 25 | -#ifdef linux | ||
| 26 | +#ifdef __linux__ | ||
| 27 | # include <asm/sgidefs.h> | ||
| 28 | #elif defined(__rtems__) | ||
| 29 | /* | ||
| 30 | -- | ||
| 31 | 2.1.4 | ||
| 32 | |||
diff --git a/meta/recipes-support/libffi/libffi/0001-mips-fix-MIPS-softfloat-build-issue.patch b/meta/recipes-support/libffi/libffi/0001-mips-fix-MIPS-softfloat-build-issue.patch deleted file mode 100644 index 61c9eb31d1..0000000000 --- a/meta/recipes-support/libffi/libffi/0001-mips-fix-MIPS-softfloat-build-issue.patch +++ /dev/null | |||
| @@ -1,177 +0,0 @@ | |||
| 1 | From 655e82c92d5c3875aee04322f1993d6b0774a7bf Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Yousong Zhou <yszhou4tech@gmail.com> | ||
| 3 | Date: Mon, 15 Aug 2016 15:00:13 +0800 | ||
| 4 | Subject: [PATCH] mips: fix MIPS softfloat build issue | ||
| 5 | |||
| 6 | The patch for o32.S is taken from OpenWrt packages repo 3a7a4bf "libffi: | ||
| 7 | fix MIPS softfloat build issue with current binutils" | ||
| 8 | |||
| 9 | Signed-off-by: Felix Fietkau <nbd@openwrt.org> | ||
| 10 | Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com> | ||
| 11 | --- | ||
| 12 | Upstream-Status: Backport [https://github.com/libffi/libffi/commit/2ded2a4f494165c93293afc14ab0be1243cf8c49] | ||
| 13 | src/mips/n32.S | 17 +++++++++++++++++ | ||
| 14 | src/mips/o32.S | 17 +++++++++++++++++ | ||
| 15 | 2 files changed, 34 insertions(+) | ||
| 16 | |||
| 17 | diff --git a/src/mips/n32.S b/src/mips/n32.S | ||
| 18 | index c6985d3..8f25994 100644 | ||
| 19 | --- a/src/mips/n32.S | ||
| 20 | +++ b/src/mips/n32.S | ||
| 21 | @@ -107,6 +107,16 @@ loadregs: | ||
| 22 | |||
| 23 | REG_L t6, 3*FFI_SIZEOF_ARG($fp) # load the flags word into t6. | ||
| 24 | |||
| 25 | +#ifdef __mips_soft_float | ||
| 26 | + REG_L a0, 0*FFI_SIZEOF_ARG(t9) | ||
| 27 | + REG_L a1, 1*FFI_SIZEOF_ARG(t9) | ||
| 28 | + REG_L a2, 2*FFI_SIZEOF_ARG(t9) | ||
| 29 | + REG_L a3, 3*FFI_SIZEOF_ARG(t9) | ||
| 30 | + REG_L a4, 4*FFI_SIZEOF_ARG(t9) | ||
| 31 | + REG_L a5, 5*FFI_SIZEOF_ARG(t9) | ||
| 32 | + REG_L a6, 6*FFI_SIZEOF_ARG(t9) | ||
| 33 | + REG_L a7, 7*FFI_SIZEOF_ARG(t9) | ||
| 34 | +#else | ||
| 35 | and t4, t6, ((1<<FFI_FLAG_BITS)-1) | ||
| 36 | REG_L a0, 0*FFI_SIZEOF_ARG(t9) | ||
| 37 | beqz t4, arg1_next | ||
| 38 | @@ -193,6 +203,7 @@ arg7_next: | ||
| 39 | arg8_doublep: | ||
| 40 | l.d $f19, 7*FFI_SIZEOF_ARG(t9) | ||
| 41 | arg8_next: | ||
| 42 | +#endif | ||
| 43 | |||
| 44 | callit: | ||
| 45 | # Load the function pointer | ||
| 46 | @@ -214,6 +225,7 @@ retint: | ||
| 47 | b epilogue | ||
| 48 | |||
| 49 | retfloat: | ||
| 50 | +#ifndef __mips_soft_float | ||
| 51 | bne t6, FFI_TYPE_FLOAT, retdouble | ||
| 52 | jal t9 | ||
| 53 | REG_L t4, 4*FFI_SIZEOF_ARG($fp) | ||
| 54 | @@ -272,6 +284,7 @@ retstruct_f_d: | ||
| 55 | s.s $f0, 0(t4) | ||
| 56 | s.d $f2, 8(t4) | ||
| 57 | b epilogue | ||
| 58 | +#endif | ||
| 59 | |||
| 60 | retstruct_d_soft: | ||
| 61 | bne t6, FFI_TYPE_STRUCT_D_SOFT, retstruct_f_soft | ||
| 62 | @@ -429,6 +442,7 @@ ffi_closure_N32: | ||
| 63 | REG_S a6, A6_OFF2($sp) | ||
| 64 | REG_S a7, A7_OFF2($sp) | ||
| 65 | |||
| 66 | +#ifndef __mips_soft_float | ||
| 67 | # Store all possible float/double registers. | ||
| 68 | s.d $f12, F12_OFF2($sp) | ||
| 69 | s.d $f13, F13_OFF2($sp) | ||
| 70 | @@ -438,6 +452,7 @@ ffi_closure_N32: | ||
| 71 | s.d $f17, F17_OFF2($sp) | ||
| 72 | s.d $f18, F18_OFF2($sp) | ||
| 73 | s.d $f19, F19_OFF2($sp) | ||
| 74 | +#endif | ||
| 75 | |||
| 76 | # Call ffi_closure_mips_inner_N32 to do the real work. | ||
| 77 | LA t9, ffi_closure_mips_inner_N32 | ||
| 78 | @@ -458,6 +473,7 @@ cls_retint: | ||
| 79 | b cls_epilogue | ||
| 80 | |||
| 81 | cls_retfloat: | ||
| 82 | +#ifndef __mips_soft_float | ||
| 83 | bne v0, FFI_TYPE_FLOAT, cls_retdouble | ||
| 84 | l.s $f0, V0_OFF2($sp) | ||
| 85 | b cls_epilogue | ||
| 86 | @@ -500,6 +516,7 @@ cls_retstruct_f_d: | ||
| 87 | l.s $f0, V0_OFF2($sp) | ||
| 88 | l.d $f2, V1_OFF2($sp) | ||
| 89 | b cls_epilogue | ||
| 90 | +#endif | ||
| 91 | |||
| 92 | cls_retstruct_small2: | ||
| 93 | REG_L v0, V0_OFF2($sp) | ||
| 94 | diff --git a/src/mips/o32.S b/src/mips/o32.S | ||
| 95 | index eb27981..429dd0a 100644 | ||
| 96 | --- a/src/mips/o32.S | ||
| 97 | +++ b/src/mips/o32.S | ||
| 98 | @@ -82,13 +82,16 @@ sixteen: | ||
| 99 | |||
| 100 | ADDU $sp, 4 * FFI_SIZEOF_ARG # adjust $sp to new args | ||
| 101 | |||
| 102 | +#ifndef __mips_soft_float | ||
| 103 | bnez t0, pass_d # make it quick for int | ||
| 104 | +#endif | ||
| 105 | REG_L a0, 0*FFI_SIZEOF_ARG($sp) # just go ahead and load the | ||
| 106 | REG_L a1, 1*FFI_SIZEOF_ARG($sp) # four regs. | ||
| 107 | REG_L a2, 2*FFI_SIZEOF_ARG($sp) | ||
| 108 | REG_L a3, 3*FFI_SIZEOF_ARG($sp) | ||
| 109 | b call_it | ||
| 110 | |||
| 111 | +#ifndef __mips_soft_float | ||
| 112 | pass_d: | ||
| 113 | bne t0, FFI_ARGS_D, pass_f | ||
| 114 | l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args | ||
| 115 | @@ -130,6 +133,7 @@ pass_f_d: | ||
| 116 | # bne t0, FFI_ARGS_F_D, call_it | ||
| 117 | l.s $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args | ||
| 118 | l.d $f14, 2*FFI_SIZEOF_ARG($sp) # passing double and float | ||
| 119 | +#endif | ||
| 120 | |||
| 121 | call_it: | ||
| 122 | # Load the function pointer | ||
| 123 | @@ -158,14 +162,23 @@ retfloat: | ||
| 124 | bne t2, FFI_TYPE_FLOAT, retdouble | ||
| 125 | jalr t9 | ||
| 126 | REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) | ||
| 127 | +#ifndef __mips_soft_float | ||
| 128 | s.s $f0, 0(t0) | ||
| 129 | +#else | ||
| 130 | + REG_S v0, 0(t0) | ||
| 131 | +#endif | ||
| 132 | b epilogue | ||
| 133 | |||
| 134 | retdouble: | ||
| 135 | bne t2, FFI_TYPE_DOUBLE, noretval | ||
| 136 | jalr t9 | ||
| 137 | REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) | ||
| 138 | +#ifndef __mips_soft_float | ||
| 139 | s.d $f0, 0(t0) | ||
| 140 | +#else | ||
| 141 | + REG_S v1, 4(t0) | ||
| 142 | + REG_S v0, 0(t0) | ||
| 143 | +#endif | ||
| 144 | b epilogue | ||
| 145 | |||
| 146 | noretval: | ||
| 147 | @@ -261,9 +274,11 @@ $LCFI7: | ||
| 148 | li $13, 1 # FFI_O32 | ||
| 149 | bne $16, $13, 1f # Skip fp save if FFI_O32_SOFT_FLOAT | ||
| 150 | |||
| 151 | +#ifndef __mips_soft_float | ||
| 152 | # Store all possible float/double registers. | ||
| 153 | s.d $f12, FA_0_0_OFF2($fp) | ||
| 154 | s.d $f14, FA_1_0_OFF2($fp) | ||
| 155 | +#endif | ||
| 156 | 1: | ||
| 157 | # Call ffi_closure_mips_inner_O32 to do the work. | ||
| 158 | la t9, ffi_closure_mips_inner_O32 | ||
| 159 | @@ -281,6 +296,7 @@ $LCFI7: | ||
| 160 | li $13, 1 # FFI_O32 | ||
| 161 | bne $16, $13, 1f # Skip fp restore if FFI_O32_SOFT_FLOAT | ||
| 162 | |||
| 163 | +#ifndef __mips_soft_float | ||
| 164 | li $9, FFI_TYPE_FLOAT | ||
| 165 | l.s $f0, V0_OFF2($fp) | ||
| 166 | beq $8, $9, closure_done | ||
| 167 | @@ -288,6 +304,7 @@ $LCFI7: | ||
| 168 | li $9, FFI_TYPE_DOUBLE | ||
| 169 | l.d $f0, V0_OFF2($fp) | ||
| 170 | beq $8, $9, closure_done | ||
| 171 | +#endif | ||
| 172 | 1: | ||
| 173 | REG_L $3, V1_OFF2($fp) | ||
| 174 | REG_L $2, V0_OFF2($fp) | ||
| 175 | -- | ||
| 176 | 2.9.3 | ||
| 177 | |||
diff --git a/meta/recipes-support/libffi/libffi/not-win32.patch b/meta/recipes-support/libffi/libffi/not-win32.patch index 80c40a4742..86a7fc9e40 100644 --- a/meta/recipes-support/libffi/libffi/not-win32.patch +++ b/meta/recipes-support/libffi/libffi/not-win32.patch | |||
| @@ -11,12 +11,10 @@ As this block is generally pointless, disable it. | |||
| 11 | Upstream-Status: Inappropriate | 11 | Upstream-Status: Inappropriate |
| 12 | Signed-off-by: Ross Burton <ross.burton@intel.com> | 12 | Signed-off-by: Ross Burton <ross.burton@intel.com> |
| 13 | 13 | ||
| 14 | Index: libffi-3.2.1/configure.ac | 14 | --- a/configure.ac |
| 15 | =================================================================== | 15 | +++ b/configure.ac |
| 16 | --- libffi-3.2.1.orig/configure.ac | 16 | @@ -350,7 +350,7 @@ AC_ARG_ENABLE(multi-os-directory, |
| 17 | +++ libffi-3.2.1/configure.ac | 17 | |
| 18 | @@ -592,7 +592,7 @@ AC_ARG_ENABLE(purify-safety, | ||
| 19 | |||
| 20 | # These variables are only ever used when we cross-build to X86_WIN32. | 18 | # These variables are only ever used when we cross-build to X86_WIN32. |
| 21 | # And we only support this with GCC, so... | 19 | # And we only support this with GCC, so... |
| 22 | -if test "x$GCC" = "xyes"; then | 20 | -if test "x$GCC" = "xyes"; then |
diff --git a/meta/recipes-support/libffi/libffi_3.2.1.bb b/meta/recipes-support/libffi/libffi_3.3~rc0.bb index f2c684a7a6..dadde0b2a0 100644 --- a/meta/recipes-support/libffi/libffi_3.2.1.bb +++ b/meta/recipes-support/libffi/libffi_3.3~rc0.bb | |||
| @@ -10,20 +10,21 @@ A layer must exist above `libffi' that handles type conversions for values passe | |||
| 10 | LICENSE = "MIT" | 10 | LICENSE = "MIT" |
| 11 | LIC_FILES_CHKSUM = "file://LICENSE;md5=3610bb17683a0089ed64055416b2ae1b" | 11 | LIC_FILES_CHKSUM = "file://LICENSE;md5=3610bb17683a0089ed64055416b2ae1b" |
| 12 | 12 | ||
| 13 | SRC_URI = "https://sourceware.org/pub/libffi/${BP}.tar.gz \ | 13 | SRC_URI = "https://github.com/libffi/libffi/releases/download/v3.3-rc0/libffi-3.3-rc0.tar.gz \ |
| 14 | file://not-win32.patch \ | 14 | file://not-win32.patch \ |
| 15 | file://0001-mips-Use-compiler-internal-define-for-linux.patch \ | ||
| 16 | file://0001-mips-fix-MIPS-softfloat-build-issue.patch \ | ||
| 17 | file://0001-libffi-Support-musl-x32-build.patch \ | ||
| 18 | file://0001-New-RISC-V-port-281.patch \ | ||
| 19 | " | 15 | " |
| 20 | 16 | SRC_URI[md5sum] = "8d2a82a78faf10a5e53c27d986e8f04e" | |
| 21 | SRC_URI[md5sum] = "83b89587607e3eb65c70d361f13bab43" | 17 | SRC_URI[sha256sum] = "403d67aabf1c05157855ea2b1d9950263fb6316536c8c333f5b9ab1eb2f20ecf" |
| 22 | SRC_URI[sha256sum] = "d06ebb8e1d9a22d19e38d63fdb83954253f39bedc5d46232a05645685722ca37" | ||
| 23 | 18 | ||
| 24 | EXTRA_OECONF += "--disable-builddir" | 19 | EXTRA_OECONF += "--disable-builddir" |
| 25 | EXTRA_OEMAKE_class-target = "LIBTOOLFLAGS='--tag=CC'" | 20 | EXTRA_OEMAKE_class-target = "LIBTOOLFLAGS='--tag=CC'" |
| 26 | inherit autotools texinfo | 21 | inherit autotools texinfo multilib_header |
| 22 | |||
| 23 | S = "${WORKDIR}/${BPN}-3.3-rc0" | ||
| 24 | |||
| 25 | do_install_append() { | ||
| 26 | oe_multilib_header ffi.h | ||
| 27 | } | ||
| 27 | 28 | ||
| 28 | FILES_${PN}-dev += "${libdir}/libffi-${PV}" | 29 | FILES_${PN}-dev += "${libdir}/libffi-${PV}" |
| 29 | 30 | ||
