24 Commits

Author SHA1 Message Date
Xiaodong Liu
9e06d18c80 [LoongArch] Add intrinsics for CACOP instruction
The CACOP instruction is mainly used for cache initialization
and cache-consistency maintenance.

Depends on D140872

Reviewed By: SixWeining

Differential Revision: https://reviews.llvm.org/D140527
2023-01-06 11:41:35 +08:00
Xiaodong Liu
63d46869ea [LoongArch] Add intrinsics for MOVFCSR2GR and MOVGR2FCSR instructions
Instruction formats:
`movgr2fcsr fcsr, rj`
`movfcsr2gr rd, fcsr`
MOVGR2FCSR modifies the value of the software writable field
corresponding to the FCSR (floating-point control and status
register) `fcsr` according to the value of the lower 32 bits of
the GR (general purpose register) `rj`.
MOVFCSR2GR sign extends the 32-bit value of the FCSR `fcsr`
and writes it into the GR `rd`.

Add "i32 @llvm.loongarch.movfcsr2gr(i32)" intrinsic for MOVFCSR2GR
instruction. The argument is FCSR register number. The return value
is the value in the FCSR.
Add "void @llvm.loongarch.movgr2fcsr(i32, i32)" intrinsic for MOVGR2FCSR
instruction. The first argument is the FCSR number, the second argument
is the value in GR.

Reviewed By: SixWeining, xen0n

Differential Revision: https://reviews.llvm.org/D140685
2023-01-04 14:11:30 +08:00
gonglingqin
e726703c27 [Clang][LoongArch] Add intrinsic for rdtime_d, rdtimeh_w and rdtimel_w
Add these intrinsics to keep consistent with GCC [1].

[1]: https://github.com/gcc-mirror/gcc/blob/master/gcc/config/loongarch/larchintrin.h#L33

Differential Revision: https://reviews.llvm.org/D139987
2022-12-22 19:21:22 +08:00
gonglingqin
aeb8f911b1 [Clang][LoongArch] Add intrinsic for asrtle, asrtgt, lddir, ldpte and cpucfg
`__cpucfg` is required by Linux [1].

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/loongarch/include/asm/loongarch.h#n59

Differential Revision: https://reviews.llvm.org/D139915
2022-12-22 18:56:34 +08:00
gonglingqin
9853c0263e [LoongArch] Test CodeGen/LoongArch/intrinsic-la32.c with -O2. NFC.
To avoid excessive redundancy in test cases, use -O2 instead of -O0
for testing.
2022-12-12 17:22:07 +08:00
gonglingqin
048612050a [Clang][LoongArch] Add intrinsic for iocsrrd and iocsrwr
These intrinsics are required by Linux [1].

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/loongarch/include/asm/loongarch.h#n240

Differential Revision: https://reviews.llvm.org/D139612
2022-12-10 14:05:19 +08:00
gonglingqin
9a5e5402cf [LoongArch] Add testcases for privileged intrinsic macros
Add testcases calling macros to the implemented privileged intrinsics
as discussed in D139288. The intrinsics involved include ibar, dbar,
break, syscall, and CRC check intrinsics.

Differential Revision: https://reviews.llvm.org/D139397
2022-12-10 11:36:56 +08:00
gonglingqin
579f3f0606 [LoongArch] Rename the test file and separate the tests on LA32 and LA64. NFC.
Use intrinsic-la32*.c to test the intrinsics of loongarch32.
Use intrinsic-la64*.c to test the intrinsics of loongarch64.
2022-12-08 16:24:45 +08:00
gonglingqin
685bbe65f5 [Clang][LoongArch] Add intrinsic for csrrd, csrwr and csrxchg
These intrinsics are required by Linux [1].

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/loongarch/include/asm/loongarch.h?h=v6.0&id=4fe89d07dcc2804c8b562f6c7896a45643d34b2f#n232

Differential Revision: https://reviews.llvm.org/D139288
2022-12-08 14:11:50 +08:00
gonglingqin
624401612c [LoongArch] Add remaining intrinsics for CRC check instructions
After D137316 implements the intrinsics of the first crc check instruction
and related diagnosis, this patch implements the intrinsics of all remaining
crc check instructions.

Differential Revision: https://reviews.llvm.org/D138418
2022-12-01 09:40:50 +08:00
gonglingqin
c2ec455f18 [LoongArch] Add intrinsics for ibar, break and syscall
Diagnostics for intrinsic input parameters have also been added.

Differential Revision: https://reviews.llvm.org/D138094
2022-11-21 09:31:26 +08:00
gonglingqin
ddbb21bdb5 [LoongArch] Add immediate operand validity check for __builtin_loongarch_dbar
Differential Revision: https://reviews.llvm.org/D137809
2022-11-16 14:47:45 +08:00
gonglingqin
da34aff90d [Clang][LoongArch] Implement __builtin_loongarch_crc_w_d_w builtin and add diagnostics
This patch adds support to prevent __builtin_loongarch_crc_w_d_w from compiling
on loongarch32 in the front end and adds diagnostics accordingly.

Reference: https://github.com/gcc-mirror/gcc/blob/master/gcc/config/loongarch/larchintrin.h#L175-L184

Depends on D136906

Differential Revision: https://reviews.llvm.org/D137316
2022-11-11 09:16:57 +08:00
gonglingqin
85f08c4197 [Clang][LoongArch] Implement __builtin_loongarch_dbar builtin
Differential Revision: https://reviews.llvm.org/D136906
2022-11-10 17:27:44 +08:00
Weining Lu
e415cb1d61 [LoongArch] Support inline asm operand modifier 'z'
Print $zero register if operand is zero, otherwise print it normally.

Clang is highly compatible [1] with GCC inline assembly extensions,
allowing the same set of constraints, modifiers and operands as GCC
inline assembly. This patch tries to make it compatible regarding
LoongArch specific operand modifiers.

GCC supports many modifiers [2], but it seems that only x86 and msp430
are documented [3][4]. I don't know if any other modifiers are being
used except the 'z' in Linux [5].

[1]: https://clang.llvm.org/compatibility.html#inline-asm
[2]: https://github.com/gcc-mirror/gcc/blob/master/gcc/config/loongarch/loongarch.cc#L4884-L4911
[3]: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#x86Operandmodifiers
[4]: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#msp430Operandmodifiers
[5]: https://github.com/torvalds/linux/blob/master/arch/loongarch/include/asm/cmpxchg.h#L17

Differential Revision: https://reviews.llvm.org/D136841
2022-10-31 09:56:41 +08:00
Weining Lu
cd0174aacb [Clang][LoongArch] Support inline asm constraint 'J'
'J' is defined in GCC [1] but not documented [2] while Linux [3] has
already used it in LoongArch port.

[1]: https://github.com/gcc-mirror/gcc/blob/master/gcc/config/loongarch/constraints.md#L61
[2]: https://gcc.gnu.org/onlinedocs/gccint/Machine-Constraints.html
[3]: https://github.com/torvalds/linux/blob/master/arch/loongarch/include/asm/cmpxchg.h#L19

Differential Revision: https://reviews.llvm.org/D136835
2022-10-31 09:13:52 +08:00
wanglei
defe7c07f0 Reland "[clang][LoongArch] Set MaxAtomicInlineWidth and MaxAtomicPromoteWidth for LoongArch"
Differential Revision: https://reviews.llvm.org/D135526
2022-10-11 20:36:09 +08:00
Weining Lu
42b70793a1 Reland "[Clang][LoongArch] Add inline asm support for constraints k/m/ZB/ZC"
Reference: https://gcc.gnu.org/onlinedocs/gccint/Machine-Constraints.html

k: A memory operand whose address is formed by a base register and
(optionally scaled) index register.

m: A memory operand whose address is formed by a base register and
offset that is suitable for use in instructions with the same
addressing mode as st.w and ld.w.

ZB: An address that is held in a general-purpose register. The offset
is zero.

ZC: A memory operand whose address is formed by a base register and
offset that is suitable for use in instructions with the same
addressing mode as ll.w and sc.w.

Note:
The INLINEASM SDNode flags in below tests are updated because the new
introduced enum `Constraint_k` is added before `Constraint_m`.
  llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll
  llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-inline-asm.ll
  llvm/test/CodeGen/X86/callbr-asm-kill.mir

This patch passes `ninja check-all` on a X86 machine with all official
targets and the LoongArch target enabled.

Differential Revision: https://reviews.llvm.org/D134638
2022-10-11 19:51:48 +08:00
Weining Lu
b32a1bdf42 Revert "[clang][LoongArch] Set MaxAtomicInlineWidth and MaxAtomicPromoteWidth for LoongArch"
This reverts commit 6547565e7bdcd9c3f683ad196b62d08c7061fdf1.

This breaks test: Preprocessor/init-loongarch.c
2022-10-11 19:21:28 +08:00
wanglei
6547565e7b [clang][LoongArch] Set MaxAtomicInlineWidth and MaxAtomicPromoteWidth for LoongArch
Differential Revision: https://reviews.llvm.org/D135526
2022-10-11 18:12:37 +08:00
Fangrui Song
04a65d62a0 Revert D134638 "[Clang][LoongArch] Add inline asm support for constraints k/m/ZB/ZC"
This reverts commit b7baddc7557e5c35a0f6a604a134d849265a99d4.

Broke CodeGen/X86/callbr-asm-kill.mir
We shall pay attention when adding new constraints.
2022-09-29 00:54:56 -07:00
Weining Lu
b7baddc755 [Clang][LoongArch] Add inline asm support for constraints k/m/ZB/ZC
k: A memory operand whose address is formed by a base register and
(optionally scaled) index register.

m: A memory operand whose address is formed by a base register and
offset that is suitable for use in instructions with the same
addressing mode as st.w and ld.w.

ZB: An address that is held in a general-purpose register. The offset
is zero.

ZC: A memory operand whose address is formed by a base register and
offset that is suitable for use in instructions with the same
addressing mode as ll.w and sc.w.

Differential Revision: https://reviews.llvm.org/D134638
2022-09-29 15:02:08 +08:00
Weining Lu
394f30919a [Clang][LoongArch] Add inline asm support for constraints f/l/I/K
This patch adds support for constraints `f`, `l`, `I`, `K` according
to [1]. The remain constraints (`k`, `m`, `ZB`, `ZC`) will be added
later as they are a little more complex than the others.
f: A floating-point register (if available).
l: A signed 16-bit constant.
I: A signed 12-bit constant (for arithmetic instructions).
K: An unsigned 12-bit constant (for logic instructions).

For now, no need to support register alias (e.g. `$a0`) in llvm as
clang will correctly decode the usage of register name aliases into
their official names. And AFAIK, the not yet upstreamed `rustc` for
LoongArch will always use official register names (e.g. `$r4`).

[1] https://gcc.gnu.org/onlinedocs/gccint/Machine-Constraints.html

Differential Revision: https://reviews.llvm.org/D134157
2022-09-26 08:49:58 +08:00
Weining Lu
7d88a05cc0 [Clang][LoongArch] Implement ABI lowering
Reuse most of RISCV's implementation with several exceptions:

1. Assign signext/zeroext attribute to args passed in stack.
On RISCV, integer scalars passed in registers have signext/zeroext
when promoted, but are anyext if passed on the stack. This is defined
in early RISCV ABI specification. But after this change [1], integers
should also be signext/zeroext if passed on the stack. So I think
RISCV's ABI lowering should be updated [2].

While in LoongArch ABI spec, we can see that integer scalars narrower
than GRLEN bits are zero/sign-extended no matter passed in registers
or on the stack.

2. Zero-width bit fields are ignored.
This matches GCC's behavior but it hasn't been documented in ABI sepc.
See https://gcc.gnu.org/r12-8294.

3. `char` is signed by default.
There is another difference worth mentioning is that `char` is signed
by default on LoongArch while it is unsigned on RISCV.

This patch also adds `_BitInt` type support to LoongArch and handle it
in LoongArchABIInfo::classifyArgumentType.

[1] cec39a064e
[2] https://github.com/llvm/llvm-project/issues/57261

Differential Revision: https://reviews.llvm.org/D132285
2022-09-19 12:05:00 +08:00