summaryrefslogtreecommitdiffstats
path: root/backends/riscv_retval.c
diff options
context:
space:
mode:
Diffstat (limited to 'backends/riscv_retval.c')
-rw-r--r--backends/riscv_retval.c86
1 files changed, 74 insertions, 12 deletions
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);
+}