diff options
| -rw-r--r-- | backends/ChangeLog | 13 | ||||
| -rw-r--r-- | backends/riscv_init.c | 21 | ||||
| -rw-r--r-- | backends/riscv_retval.c | 86 |
3 files changed, 104 insertions, 16 deletions
diff --git a/backends/ChangeLog b/backends/ChangeLog index ac0e3187..b48af4e1 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,16 @@ +2021-09-29 William Cohen <[email protected]> + + * riscv_init.c (riscv_return_value_location_lp64f): New function + declaration. + (riscv_return_value_location_lp64): Likewise. + (riscv_init): Set return_value_location based on elf class and + ehdr flags. + * riscv_retval.c (riscv_return_value_location_lp64d): Renamed to... + (riscv_return_value_location_lp64ifd): ...this. Handle single, + double, float _Complex and double _Complex cases. + (riscv_return_value_location_lp64d): New function. + (riscv_return_value_location_lp64f): Likewise. + 2021-04-19 Martin Liska <[email protected]> * aarch64_symbol.c (aarch64_data_marker_symbol): Use startswith. diff --git a/backends/riscv_init.c b/backends/riscv_init.c index 551e7bb6..141e0821 100644 --- a/backends/riscv_init.c +++ b/backends/riscv_init.c @@ -41,6 +41,12 @@ extern __typeof (EBLHOOK (return_value_location)) riscv_return_value_location_lp64d attribute_hidden; +extern __typeof (EBLHOOK (return_value_location)) + riscv_return_value_location_lp64f attribute_hidden; + +extern __typeof (EBLHOOK (return_value_location)) + riscv_return_value_location_lp64 attribute_hidden; + extern __typeof (EBLHOOK (core_note)) riscv64_core_note attribute_hidden; Ebl * @@ -63,10 +69,17 @@ riscv_init (Elf *elf, eh->core_note = riscv64_core_note; else HOOK (eh, core_note); - if (eh->class == ELFCLASS64 - && ((elf->state.elf64.ehdr->e_flags & EF_RISCV_FLOAT_ABI) - == EF_RISCV_FLOAT_ABI_DOUBLE)) - eh->return_value_location = riscv_return_value_location_lp64d; + if (eh->class == ELFCLASS64) + { + if ((elf->state.elf64.ehdr->e_flags & EF_RISCV_FLOAT_ABI) + == EF_RISCV_FLOAT_ABI_DOUBLE) + eh->return_value_location = riscv_return_value_location_lp64d; + else if ((elf->state.elf64.ehdr->e_flags & EF_RISCV_FLOAT_ABI) + == EF_RISCV_FLOAT_ABI_SINGLE) + eh->return_value_location = riscv_return_value_location_lp64f; + else + eh->return_value_location = riscv_return_value_location_lp64; + } return eh; } diff --git a/backends/riscv_retval.c b/backends/riscv_retval.c index 35b6010b..34761486 100644 --- a/backends/riscv_retval.c +++ b/backends/riscv_retval.c @@ -125,8 +125,8 @@ pass_by_flattened_arg (const Dwarf_Op **locp __attribute__ ((unused)), } int -riscv_return_value_location_lp64d (Dwarf_Die *functypedie, - const Dwarf_Op **locp) +riscv_return_value_location_lp64ifd (int fp, Dwarf_Die *functypedie, + const Dwarf_Op **locp) { /* Start with the function's type, and get the DW_AT_type attribute, which is the type of the return value. */ @@ -211,10 +211,29 @@ riscv_return_value_location_lp64d (Dwarf_Die *functypedie, switch (size) { case 4: /* single */ - case 8: /* double */ - return pass_in_fpr_lp64d (locp, size); - - case 16: /* quad */ + switch (fp) + { + case EF_RISCV_FLOAT_ABI_DOUBLE: + case EF_RISCV_FLOAT_ABI_SINGLE: + return pass_in_fpr_lp64d (locp, size); + case EF_RISCV_FLOAT_ABI_SOFT: + return pass_in_gpr_lp64 (locp, size); + default: + return -2; + } + case 8: /* double */ + switch (fp) + { + case EF_RISCV_FLOAT_ABI_DOUBLE: + return pass_in_fpr_lp64d (locp, size); + case EF_RISCV_FLOAT_ABI_SINGLE: + case EF_RISCV_FLOAT_ABI_SOFT: + return pass_in_gpr_lp64 (locp, size); + default: + return -2; + } + + case 16: /* quad */ return pass_in_gpr_lp64 (locp, size); default: @@ -227,12 +246,31 @@ riscv_return_value_location_lp64d (Dwarf_Die *functypedie, switch (size) { case 8: /* float _Complex */ - return pass_in_fpr_lp64f (locp, size); - - case 16: /* double _Complex */ - return pass_in_fpr_lp64d (locp, size); - - case 32: /* long double _Complex */ + switch (fp) + { + case EF_RISCV_FLOAT_ABI_DOUBLE: + case EF_RISCV_FLOAT_ABI_SINGLE: + return pass_in_fpr_lp64f (locp, size); + case EF_RISCV_FLOAT_ABI_SOFT: + /* Double the size so the vals are two registers. */ + return pass_in_gpr_lp64 (locp, size * 2); + default: + return -2; + } + + case 16: /* double _Complex */ + switch (fp) + { + case EF_RISCV_FLOAT_ABI_DOUBLE: + return pass_in_fpr_lp64d (locp, size); + case EF_RISCV_FLOAT_ABI_SINGLE: + case EF_RISCV_FLOAT_ABI_SOFT: + return pass_in_gpr_lp64 (locp, size); + default: + return -2; + } + + case 32: /* long double _Complex */ return pass_by_ref (locp); default: @@ -249,3 +287,27 @@ riscv_return_value_location_lp64d (Dwarf_Die *functypedie, *locp = NULL; return 0; } + +int +riscv_return_value_location_lp64d (Dwarf_Die *functypedie, + const Dwarf_Op **locp) +{ + return riscv_return_value_location_lp64ifd (EF_RISCV_FLOAT_ABI_DOUBLE, + functypedie, locp); +} + +int +riscv_return_value_location_lp64f (Dwarf_Die *functypedie, + const Dwarf_Op **locp) +{ + return riscv_return_value_location_lp64ifd (EF_RISCV_FLOAT_ABI_SINGLE, + functypedie, locp); +} + +int +riscv_return_value_location_lp64 (Dwarf_Die *functypedie, + const Dwarf_Op **locp) +{ + return riscv_return_value_location_lp64ifd (EF_RISCV_FLOAT_ABI_SOFT, + functypedie, locp); +} |
