1/* Macros for LoongArch.
2 Copyright (C) 2026 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library. If not, see
17 <https://www.gnu.org/licenses/>. */
18
19#ifndef _LOONGARCH_SYSDEP_H
20#define _LOONGARCH_SYSDEP_H
21
22#if __loongarch_grlen == 64
23
24#define PTRLOG 3
25/* Align reg to 2^n. Used in C. */
26#define REG_ALIGN_C(reg, n) \
27 "bstrins.d\t" __STRING(reg) ", $zero, (" __STRING(n) "-1), 0"
28
29#elif __loongarch_grlen == 32
30
31#define PTRLOG 2
32#define REG_ALIGN_C(reg, n) \
33 "srli.w\t" __STRING(reg)", " __STRING(reg)", " __STRING(n) "\n\t" \
34 "slli.w\t" __STRING(reg)", " __STRING(reg)", " __STRING(n)
35
36#else
37#error __loongarch_grlen must equal 32 or 64
38#endif
39
40#ifdef __ASSEMBLER__
41
42/* Stack alignment bytes. */
43#define STACK_ALIGN 16
44
45/* Macros to handle different pointer/register sizes for 32/64-bit code. */
46#if __loongarch_grlen == 64
47#define SRAI srai.d
48
49/* Align reg to 2^n. Used in assembly. */
50#define REG_ALIGN_ASM(reg, n) bstrins.d reg, zero, (n-1), 0
51
52#define LOAD_LOCAL(reg, sym) \
53 pcalau12i reg, %pc_hi20(sym); \
54 ld.d reg, reg, %pc_lo12(sym);
55
56#define LOAD_GLOBAL(reg, sym) \
57 la.got reg, sym; \
58 ld.d reg, reg, 0;
59
60#define LA_GOT(reg, sym) la.got reg, t0, sym
61
62#define CALL(sym) call36 sym
63#define TAIL(sym) tail36 t0, sym
64
65#elif __loongarch_grlen == 32 /* __loongarch_grlen == 64 */
66
67#define SRAI srai.w
68
69/* LA32R not have bstrins.w, use srli.w and slli.w on both LA32S and LA32R. */
70#define REG_ALIGN_ASM(reg, n) \
71 srli.w reg, reg, n; \
72 slli.w reg, reg, n;
73
74#define LOAD_LOCAL(reg, sym) \
75 1: pcaddu12i reg, %pcadd_hi20(sym); \
76 ld.w reg, reg, %pcadd_lo12(1b);
77
78#define LOAD_GLOBAL(reg, sym) \
79 1: pcaddu12i reg, %got_pcadd_hi20(sym); \
80 ld.w reg, reg, %pcadd_lo12(1b); \
81 ld.w reg, reg, 0;
82
83#define LA_GOT(reg, sym) la.got reg, sym
84
85#define CALL(sym) call30 sym
86#define TAIL(sym) tail30 t0, sym
87
88#else /* __loongarch_grlen == 64 */
89#error __loongarch_grlen must equal 32 or 64
90#endif /* __loongarch_grlen == 64 */
91
92#endif /* __ASSEMBLER__ */
93
94#endif /* _LOONGARCH_SYSDEP_H */