diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2003-10-10 19:14:08 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2003-10-10 19:14:08 +0000 |
commit | 3f997a978d8a747afbf345c97e1a5dcc87c17732 (patch) | |
tree | 52c01d774524fb4ae668bd39dd064504b4a1525b /gdb/sh-tdep.c | |
parent | 8be9034ab1f7c018c64a5950a600180dfc3add0f (diff) | |
download | binutils-gdb-3f997a978d8a747afbf345c97e1a5dcc87c17732.tar.gz |
* sh-tdep.c (sh_use_struct_convention): Clean up to have a
more readable code. Accomodate passing of bitfields.
Diffstat (limited to 'gdb/sh-tdep.c')
-rw-r--r-- | gdb/sh-tdep.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c index a220493f38f..eee7698b842 100644 --- a/gdb/sh-tdep.c +++ b/gdb/sh-tdep.c @@ -589,8 +589,30 @@ sh_use_struct_convention (int gcc_p, struct type *type) { int len = TYPE_LENGTH (type); int nelem = TYPE_NFIELDS (type); - return ((len != 1 && len != 2 && len != 4 && len != 8) || nelem != 1) && - (len != 8 || TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) != 4); + + /* Non-power of 2 length types and types bigger than 8 bytes (which don't + fit in two registers anyway) use struct convention. */ + if (len != 1 && len != 2 && len != 4 && len != 8) + return 1; + + /* Scalar types and aggregate types with exactly one field are aligned + by definition. They are returned in registers. */ + if (nelem <= 1) + return 0; + + /* If the first field in the aggregate has the same length as the entire + aggregate type, the type is returned in registers. */ + if (TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) == len) + return 0; + + /* If the size of the aggregate is 8 bytes and the first field is + of size 4 bytes its alignment is equal to long long's alignment, + so it's returned in registers. */ + if (len == 8 && TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) == 4) + return 0; + + /* Otherwise use struct convention. */ + return 1; } /* Extract from an array REGBUF containing the (raw) register state |