codegen: fix bug on riscv when --ptrcomp was used
[ajla.git] / ipunalg.h
blob5c2fae5e4f6e4b2d1cf22217f0413506498418c8
1 /*
2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
9 * version.
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
19 #ifndef AJLA_IPUNALGN_H
20 #define AJLA_IPUNALGN_H
22 #include "code-op.h"
24 static attr_always_inline uint8_t get_unaligned_8(const code_t *p)
26 return (uint8_t)*p;
29 static attr_always_inline uint16_t get_unaligned_16(const code_t *p)
31 return *p;
34 static attr_always_inline uint32_t get_unaligned_32(const code_t *p)
36 #if ((defined(C_LITTLE_ENDIAN) && !CODE_ENDIAN) || (defined(C_BIG_ENDIAN) && CODE_ENDIAN)) && defined(UNALIGNED_ACCESS)
37 struct unaligned_32 { uint32_t val; } attr_unaligned;
38 return cast_ptr(const struct unaligned_32 *, p)->val;
39 #else
40 return (uint32_t)p[CODE_ENDIAN] | ((uint32_t)p[!CODE_ENDIAN] << 16);
41 #endif
44 #if TYPE_FIXED_N >= 4
45 static inline uint64_t get_unaligned_64(const code_t *p)
47 #if ((defined(C_LITTLE_ENDIAN) && !CODE_ENDIAN) || (defined(C_BIG_ENDIAN) && CODE_ENDIAN)) && defined(UNALIGNED_ACCESS)
48 struct unaligned_64 { uint64_t val; } attr_unaligned;
49 return cast_ptr(const struct unaligned_64 *, p)->val;
50 #else
51 return (uint64_t)p[0 ^ (CODE_ENDIAN * 3)] | ((uint64_t)p[1 ^ (CODE_ENDIAN * 3)] << 16) | ((uint64_t)p[2 ^ (CODE_ENDIAN * 3)] << 32) | ((uint64_t)p[3 ^ (CODE_ENDIAN * 3)] << 48);
52 #endif
54 #endif
56 #if TYPE_FIXED_N >= 5
57 static inline uint128_t get_unaligned_128(const code_t *p)
59 #if ((defined(C_LITTLE_ENDIAN) && !CODE_ENDIAN) || (defined(C_BIG_ENDIAN) && CODE_ENDIAN)) && defined(UNALIGNED_ACCESS)
60 struct unaligned_128 { uint128_t val; } attr_unaligned;
61 return cast_ptr(const struct unaligned_128 *, p)->val;
62 #else
63 return get_unaligned_64(p + CODE_ENDIAN * 4) | ((uint128_t)get_unaligned_64(p + (4 - CODE_ENDIAN * 4)) << 64);
64 #endif
66 #endif
68 #endif