From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) by sourceware.org (Postfix) with ESMTPS id 1D5A5385828A for ; Tue, 2 Jan 2024 20:17:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1D5A5385828A Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 1D5A5385828A Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1033 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704226662; cv=none; b=e7/Fm4AK8g/66xu5CK2G7N4Kyjy0RoesgeBRypRDTLFJvMZl8iW5HAUwvswx+YXWv5OVu50+0t1ldmVFVpNvpgoCjC2WmgPg4m/TYP3RpLBb7HHStTOZ660/6GhBxlDvL2tFhPfMeNikw2vGYCZfNLr+aF8DCN76/vYS3ksI36o= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704226662; c=relaxed/simple; bh=FscdfUWm7EPZj9SkiyT+tWvzLVsWnS/gK9OnTEFWNII=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=kSgYUlH0uvKpljtrEIuwtN/YaVP9K4eXouPJmxYWN6EL60JBSb7wGkaUoE3JB/mKolx6VQcxa0IExFzuDh667KsaBwwKwY+7xamRGYkmj9INxKh+nmCWW1lvX3Py36LnN0wyM2C3DBcSXyvZXSlEeFYj+DseCn5SSaG9pv70PNQ= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pj1-x1033.google.com with SMTP id 98e67ed59e1d1-28cc07d8876so842395a91.1 for ; Tue, 02 Jan 2024 12:17:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1704226656; x=1704831456; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=hvjs7sbo6+6DEOIzjRPG0ufjsXrWWgSh7s+hfZTV2yQ=; b=fL8JmGryAeacreUJVl3qlwAn8eL+vttKglPkTcyMCZtUVb+uplEID7n/yLuIGC3lE+ zJrWTuOlG7Hf0/2nowGsUeThciYNDkTRSuDDxSWNvad9pEEtyj58Qm5kmtkoC8DcehTZ z1TL4S/caW9JrY4xUjIeaFUmVw/0mT0Wr6uG9lp430MU6zSnf+6P1vwLO9BdOXoCYm0g /dmG+cpz0OyBdAVpQ9ZUKIJLaNfjl9B1m4j3zavRxetCFBWo3aYIgpuVJsNra5rNJ+1X 1NbmpRZ/R2t03aIrH/CmS2LW/wZwX9JUlsUNUsVmeTFNuHKBbsd5iHvGRHqCrB5cDxWv +DWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704226656; x=1704831456; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=hvjs7sbo6+6DEOIzjRPG0ufjsXrWWgSh7s+hfZTV2yQ=; b=XKH2pzduW5Jox5b6ZKiMT+2324XClvW+SD8iS0XpqURIEric7xgBHKKY3BRmKljRpo kJTgxCETSZU9Ell56TqkKpbk60jOdZX5oAZTYrKtgt8E37DOu/BAVW2Hm5ifHAi8IHt9 G7DFGGeRJulq3KmqTMbWqVDwV+TZ+lmiyDnXDGoK9V04lEckVlSShnA200EuNJtp3Fy9 Di7v7nKPxgfecyCoLQ0TM6PB9ZrR9cDnKhlPaa6VcZ6Ko2LPWNkMyie67z21VywQmN7u 8cEb0oYgXvUGXs25NUjdH790KfvCIojkHqNQBQioCsGCmlYXCWYuuPmpT7z5i2woIVRB 3ngg== X-Gm-Message-State: AOJu0YwmwQZcVuSZUyCHsDmFnYgF9EatG2Vt6/y+pUcet98GzdtaZXHU NgsZB+CY9NoouJjk7UK+dMD/fZicxvQ3C+Z4 X-Google-Smtp-Source: AGHT+IHEb+X2YPrQLUasn4Px0L0HhL8c/4aX+uMVY8Y4eUjUTf34vjmMuQ9XK0hPvnJttPshPqk7hQ== X-Received: by 2002:a17:90a:e2d6:b0:28b:c659:72d2 with SMTP id fr22-20020a17090ae2d600b0028bc65972d2mr6089323pjb.79.1704226656278; Tue, 02 Jan 2024 12:17:36 -0800 (PST) Received: from localhost.localdomain ([111.163.121.134]) by smtp.googlemail.com with ESMTPSA id l6-20020a17090add8600b00274b035246esm10328275pjv.1.2024.01.02.12.17.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Jan 2024 12:17:35 -0800 (PST) From: trdthg47@gmail.com To: gcc-patches@gcc.gnu.org Cc: trdthg Subject: [PATCH] RISC-V: Implement ZACAS extensions Date: Wed, 3 Jan 2024 04:17:20 +0800 Message-Id: <20240102201720.1526-1-trdthg47@gmail.com> X-Mailer: git-send-email 2.40.1.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: trdthg This patch supports Zacas extension. It includes instruction's machine description and built-in functions. gcc/ChangeLog: * common/config/riscv/riscv-common.cc (riscv_implied_info): Add zacas extensions. (riscv_ext_version_table): Likewise. * config/riscv/arch-canonicalize (IMPLIED_EXT): Add zacas extensions. * config/riscv/iterators.md (SIDI): New iterator. (SIDITI): Likewise. (amocas): New attribute. * config/riscv/riscv-builtins.cc (AVAIL): Add new. * config/riscv/riscv-ftypes.def: Add new type for zacas instructions. * config/riscv/riscv-zacas.def: Add ZACAS extension's built-in function file. * config/riscv/riscv.md: Add new type for zacas instructions. * config/riscv/riscv.opt: Add introduction of riscv_zacas_subext. * config/riscv/zacas.md: Add ZACAS extension's machine description file. gcc/testsuite/ChangeLog: * gcc.target/riscv/zacas32.c: New test. * gcc.target/riscv/zacas64.c: New test. * gcc.target/riscv/zacas128.c: New test. Signed-off-by: trdthg --- gcc/common/config/riscv/riscv-common.cc | 5 ++ gcc/config/riscv/arch-canonicalize | 1 + gcc/config/riscv/iterators.md | 9 +++ gcc/config/riscv/riscv-builtins.cc | 85 ++++++++++++++++++++++- gcc/config/riscv/riscv-ftypes.def | 3 + gcc/config/riscv/riscv-zacas.def | 11 +++ gcc/config/riscv/riscv.md | 5 +- gcc/config/riscv/riscv.opt | 2 + gcc/config/riscv/zacas.md | 52 ++++++++++++++ gcc/testsuite/gcc.target/riscv/zacas128.c | 19 +++++ gcc/testsuite/gcc.target/riscv/zacas32.c | 34 +++++++++ gcc/testsuite/gcc.target/riscv/zacas64.c | 34 +++++++++ 12 files changed, 257 insertions(+), 3 deletions(-) create mode 100644 gcc/config/riscv/riscv-zacas.def create mode 100644 gcc/config/riscv/zacas.md create mode 100644 gcc/testsuite/gcc.target/riscv/zacas128.c create mode 100644 gcc/testsuite/gcc.target/riscv/zacas32.c create mode 100644 gcc/testsuite/gcc.target/riscv/zacas64.c diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index f20d179568d..14de9968c9e 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -77,6 +77,8 @@ static const riscv_implied_info_t riscv_implied_info[] = {"f", "zicsr"}, {"d", "zicsr"}, + {"zacas", "a"}, + {"zdinx", "zfinx"}, {"zfinx", "zicsr"}, {"zdinx", "zicsr"}, @@ -251,6 +253,8 @@ static const struct riscv_ext_version riscv_ext_version_table[] = {"zawrs", ISA_SPEC_CLASS_NONE, 1, 0}, + {"zacas", ISA_SPEC_CLASS_NONE, 1, 0}, + {"zba", ISA_SPEC_CLASS_NONE, 1, 0}, {"zbb", ISA_SPEC_CLASS_NONE, 1, 0}, {"zbc", ISA_SPEC_CLASS_NONE, 1, 0}, @@ -1624,6 +1628,7 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = {"zicond", &gcc_options::x_riscv_zi_subext, MASK_ZICOND}, {"zawrs", &gcc_options::x_riscv_za_subext, MASK_ZAWRS}, + {"zacas", &gcc_options::x_riscv_za_subext, MASK_ZACAS}, {"zba", &gcc_options::x_riscv_zb_subext, MASK_ZBA}, {"zbb", &gcc_options::x_riscv_zb_subext, MASK_ZBB}, diff --git a/gcc/config/riscv/arch-canonicalize b/gcc/config/riscv/arch-canonicalize index a8f47a1752b..616e0ed4726 100755 --- a/gcc/config/riscv/arch-canonicalize +++ b/gcc/config/riscv/arch-canonicalize @@ -41,6 +41,7 @@ LONG_EXT_PREFIXES = ['z', 's', 'h', 'x'] IMPLIED_EXT = { "d" : ["f", "zicsr"], "f" : ["zicsr"], + "zacas" : ["a"], "zdinx" : ["zfinx", "zicsr"], "zfinx" : ["zicsr"], "zhinx" : ["zhinxmin", "zfinx", "zicsr"], diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md index f332fba7031..b16b3892969 100644 --- a/gcc/config/riscv/iterators.md +++ b/gcc/config/riscv/iterators.md @@ -53,6 +53,12 @@ (define_mode_iterator SHORT [QI HI]) ;; Iterator for HImode constant generation. (define_mode_iterator HISI [HI SI]) +;; Iterator for SImode and DImode constant generation. +(define_mode_iterator SIDI [SI DI]) + +;; Iterator for SImode, DImode and TImode constant generation. +(define_mode_iterator SIDITI [SI DI TI]) + ;; Iterator for QImode extension patterns. (define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")]) @@ -113,6 +119,9 @@ (define_mode_attr ifmt [(SI "w") (DI "l")]) ;; This attribute gives the format suffix for atomic memory operations. (define_mode_attr amo [(SI "w") (DI "d")]) +;; This attribute gives the format suffix for amocas operations. +(define_mode_attr amocas [(SI "w") (DI "d") (TI "q")]) + ;; This attribute gives the upper-case mode name for one unit of a ;; floating-point mode. (define_mode_attr UNITMODE [(HF "HF") (SF "SF") (DF "DF")]) diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc index 5ee11ebe3bc..5074acfd69b 100644 --- a/gcc/config/riscv/riscv-builtins.cc +++ b/gcc/config/riscv/riscv-builtins.cc @@ -41,6 +41,10 @@ along with GCC; see the file COPYING3. If not see #include "backend.h" #include "gimple.h" #include "gimple-iterator.h" +#include "alias.h" +#include "emit-rtl.h" +#include "builtins.h" +#include "explow.h" /* Macros to create an enumeration identifier for a function prototype. */ #define RISCV_FTYPE_NAME0(A) RISCV_##A##_FTYPE @@ -49,6 +53,8 @@ along with GCC; see the file COPYING3. If not see #define RISCV_FTYPE_NAME3(A, B, C, D) RISCV_##A##_FTYPE_##B##_##C##_##D #define RISCV_FTYPE_NAME4(A, B, C, D, E) \ RISCV_##A##_FTYPE_##B##_##C##_##D##_##E +#define RISCV_FTYPE_NAME5(A, B, C, D, E, F) \ + RISCV_##A##_FTYPE_##B##_##C##_##D##_##E##_##F /* Classifies the prototype of a built-in function. */ enum riscv_function_type { @@ -64,7 +70,10 @@ enum riscv_builtin_type { RISCV_BUILTIN_DIRECT, /* Likewise, but with return type VOID. */ - RISCV_BUILTIN_DIRECT_NO_TARGET + RISCV_BUILTIN_DIRECT_NO_TARGET, + + /* for zacas. */ + RISCV_BUILTIN_ZACAS, }; /* Declare an availability predicate for built-in functions. */ @@ -101,6 +110,9 @@ AVAIL (flush32, TARGET_ZICBOM && !TARGET_64BIT) AVAIL (flush64, TARGET_ZICBOM && TARGET_64BIT) AVAIL (inval32, TARGET_ZICBOM && !TARGET_64BIT) AVAIL (inval64, TARGET_ZICBOM && TARGET_64BIT) +AVAIL (zacas_amocas32, TARGET_ZACAS && !TARGET_64BIT) +AVAIL (zacas_amocas64, TARGET_ZACAS && TARGET_64BIT) +AVAIL (zacas_amocas128, TARGET_ZACAS && TARGET_64BIT) AVAIL (zero32, TARGET_ZICBOZ && !TARGET_64BIT) AVAIL (zero64, TARGET_ZICBOZ && TARGET_64BIT) AVAIL (prefetchi32, TARGET_ZICBOP && !TARGET_64BIT) @@ -168,6 +180,8 @@ AVAIL (cvelw, TARGET_XCVELW && !TARGET_64BIT) #define RISCV_ATYPE_QI intQI_type_node #define RISCV_ATYPE_HI intHI_type_node #define RISCV_ATYPE_SI intSI_type_node +#define RISCV_ATYPE_DI intDI_type_node +#define RISCV_ATYPE_TI intTI_type_node #define RISCV_ATYPE_VOID_PTR ptr_type_node #define RISCV_ATYPE_INT_PTR integer_ptr_type_node @@ -184,10 +198,14 @@ AVAIL (cvelw, TARGET_XCVELW && !TARGET_64BIT) #define RISCV_FTYPE_ATYPES4(A, B, C, D, E) \ RISCV_ATYPE_##A, RISCV_ATYPE_##B, RISCV_ATYPE_##C, RISCV_ATYPE_##D, \ RISCV_ATYPE_##E +#define RISCV_FTYPE_ATYPES5(A, B, C, D, E, F) \ + RISCV_ATYPE_##A, RISCV_ATYPE_##B, RISCV_ATYPE_##C, RISCV_ATYPE_##D, \ + RISCV_ATYPE_##E, RISCV_ATYPE_##F static const struct riscv_builtin_description riscv_builtins[] = { #include "riscv-cmo.def" #include "riscv-scalar-crypto.def" + #include "riscv-zacas.def" #include "corev.def" DIRECT_BUILTIN (frflags, RISCV_USI_FTYPE, hard_float), @@ -305,6 +323,32 @@ riscv_prepare_builtin_arg (struct expand_operand *op, tree exp, unsigned argno) create_input_operand (op, expand_normal (arg), TYPE_MODE (TREE_TYPE (arg))); } +static rtx +get_builtin_sync_mem (tree loc, machine_mode mode) +{ + rtx addr, mem; + int addr_space = TYPE_ADDR_SPACE (POINTER_TYPE_P (TREE_TYPE (loc)) + ? TREE_TYPE (TREE_TYPE (loc)) + : TREE_TYPE (loc)); + scalar_int_mode addr_mode = targetm.addr_space.address_mode (addr_space); + + addr = expand_expr (loc, NULL_RTX, addr_mode, EXPAND_SUM); + addr = convert_memory_address (addr_mode, addr); + mem = gen_rtx_MEM (mode, addr); + + set_mem_addr_space (mem, addr_space); + + mem = validize_mem (mem); + + /* The alignment needs to be at least according to that of the mode. */ + set_mem_align (mem, MAX (GET_MODE_ALIGNMENT (mode), + get_pointer_alignment (loc))); + set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); + MEM_VOLATILE_P (mem) = 1; + + return mem; +} + /* Expand instruction ICODE as part of a built-in function sequence. Use the first NOPS elements of OPS as the instruction's operands. HAS_TARGET_P is true if operand 0 is a target; it is false if the @@ -350,6 +394,40 @@ riscv_expand_builtin_direct (enum insn_code icode, rtx target, tree exp, return riscv_expand_builtin_insn (icode, opno, ops, has_target_p); } +static rtx +riscv_expand_builtin_zacas (enum insn_code icode, tree exp) +{ + struct expand_operand ops[5]; + + int opno = 0; + gcc_assert (call_expr_nargs (exp) + == insn_data[icode].n_generator_args); + for (int argno = 0; argno < call_expr_nargs (exp); argno++) + { + expand_operand *op = &ops[opno++]; + tree arg = CALL_EXPR_ARG (exp, argno); + machine_mode mode = TYPE_MODE (TREE_TYPE (arg)); + switch (argno) + { + case 0: + create_fixed_operand (op, get_builtin_sync_mem (arg, mode)); + break; + case 3: + case 4: + { + enum memmodel model = memmodel_from_int (INTVAL (expand_normal (arg))); + create_integer_operand (op, model); + break; + } + default: + create_input_operand (op, expand_normal (arg), mode); + break; + } + } + + return riscv_expand_builtin_insn (icode, opno, ops, false); +} + /* Implement TARGET_GIMPLE_FOLD_BUILTIN. */ bool @@ -402,7 +480,10 @@ riscv_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, case RISCV_BUILTIN_DIRECT_NO_TARGET: return riscv_expand_builtin_direct (d->icode, target, exp, false); - } + + case RISCV_BUILTIN_ZACAS: + return riscv_expand_builtin_zacas (d->icode, exp); + } } } diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def index 3e7d5c69503..6cb8a11b1ea 100644 --- a/gcc/config/riscv/riscv-ftypes.def +++ b/gcc/config/riscv/riscv-ftypes.def @@ -51,5 +51,8 @@ DEF_RISCV_FTYPE (3, (USI, USI, USI, UQI)) DEF_RISCV_FTYPE (3, (USI, USI, USI, USI)) DEF_RISCV_FTYPE (3, (SI, SI, SI, UQI)) DEF_RISCV_FTYPE (3, (SI, SI, SI, SI)) +DEF_RISCV_FTYPE (5, (VOID, VOID_PTR, SI, SI, SI, SI)) +DEF_RISCV_FTYPE (5, (VOID, VOID_PTR, DI, DI, SI, SI)) +DEF_RISCV_FTYPE (5, (VOID, VOID_PTR, TI, TI, SI, SI)) DEF_RISCV_FTYPE (4, (USI, USI, USI, USI, UQI)) DEF_RISCV_FTYPE (4, (SI, SI, SI, SI, UQI)) diff --git a/gcc/config/riscv/riscv-zacas.def b/gcc/config/riscv/riscv-zacas.def new file mode 100644 index 00000000000..23e175cf5f7 --- /dev/null +++ b/gcc/config/riscv/riscv-zacas.def @@ -0,0 +1,11 @@ +// ZACAS +RISCV_BUILTIN (amocas32si, "amocas32", RISCV_BUILTIN_ZACAS, + RISCV_VOID_FTYPE_VOID_PTR_SI_SI_SI_SI, zacas_amocas32), +RISCV_BUILTIN (amocas64si, "amocas32", RISCV_BUILTIN_ZACAS, + RISCV_VOID_FTYPE_VOID_PTR_SI_SI_SI_SI, zacas_amocas64), +RISCV_BUILTIN (amocas32di, "amocas64", RISCV_BUILTIN_ZACAS, + RISCV_VOID_FTYPE_VOID_PTR_DI_DI_SI_SI, zacas_amocas32), +RISCV_BUILTIN (amocas64di, "amocas64", RISCV_BUILTIN_ZACAS, + RISCV_VOID_FTYPE_VOID_PTR_DI_DI_SI_SI, zacas_amocas64), +RISCV_BUILTIN (amocas64ti, "amocas128", RISCV_BUILTIN_ZACAS, + RISCV_VOID_FTYPE_VOID_PTR_TI_TI_SI_SI, zacas_amocas64), diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 52c5ce30115..4c379625e4b 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -318,6 +318,7 @@ (define_attr "ext_enabled" "no,yes" ;; clmul clmul, clmulh, clmulr ;; rotate rotation instructions ;; atomic atomic instructions +;; zacas zacas instructions ;; condmove conditional moves ;; cbo cache block instructions ;; crypto cryptography instructions @@ -461,7 +462,8 @@ (define_attr "type" mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul, fmadd,fdiv,fcmp,fcvt,fsqrt,multi,auipc,sfb_alu,nop,trap,ghost,bitmanip, rotate,clmul,min,max,minu,maxu,clz,ctz,cpop, - atomic,condmove,cbo,crypto,pushpop,mvpair,zicond,rdvlenb,rdvl,wrvxrm,wrfrm, + atomic,zacas,condmove,cbo,crypto,pushpop,mvpair,zicond,rdvlenb,rdvl,wrvxrm, + wrfrm, rdfrm,vsetvl,vsetvl_pre,vlde,vste,vldm,vstm,vlds,vsts, vldux,vldox,vstux,vstox,vldff,vldr,vstr, vlsegde,vssegte,vlsegds,vssegts,vlsegdux,vlsegdox,vssegtux,vssegtox,vlsegdff, @@ -3817,6 +3819,7 @@ (define_insn "*large_load_address" (include "generic-ooo.md") (include "vector.md") (include "vector-crypto.md") +(include "zacas.md") (include "zicond.md") (include "sfb.md") (include "zc.md") diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index cf207d4dcdf..648fa42d9d0 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -230,6 +230,8 @@ int riscv_za_subext Mask(ZAWRS) Var(riscv_za_subext) +Mask(ZACAS) Var(riscv_za_subext) + TargetVariable int riscv_zb_subext diff --git a/gcc/config/riscv/zacas.md b/gcc/config/riscv/zacas.md new file mode 100644 index 00000000000..527b6b72bba --- /dev/null +++ b/gcc/config/riscv/zacas.md @@ -0,0 +1,52 @@ +(define_c_enum "unspec" [ + ;; Zacas + UNSPEC_AMOCAS +]) + +(define_insn "riscv_amocas32" + [(unspec_volatile [(match_operand:SI 0 "memory_operand" "+A") ;; memory + (match_operand:SIDI 1 "register_operand" "r") ;; expected + (match_operand:SIDI 2 "register_operand" "r") ;; desired + (match_operand:SI 3 "const_int_operand") ;; mod_s + (match_operand:SI 4 "const_int_operand")] ;; mod_f + UNSPEC_AMOCAS)] + "TARGET_ZACAS && !TARGET_64BIT" + { + enum memmodel model_success = (enum memmodel) INTVAL (operands[3]); + enum memmodel model_failure = (enum memmodel) INTVAL (operands[4]); + enum memmodel model = riscv_union_memmodels (model_success, model_failure); + + if (model == MEMMODEL_SEQ_CST || model == MEMMODEL_ACQ_REL) + return "amocas..aqrl\t%1,%2,%0"; + else if (model == MEMMODEL_ACQUIRE) + return "amocas..aq\t%1,%2,%0"; + else if (model == MEMMODEL_RELEASE) + return "amocas..rl\t%1,%2,%0"; + else + return "amocas.\t%1,%2,%0"; + } + [(set_attr "type" "zacas")]) + +(define_insn "riscv_amocas64" + [(unspec_volatile [(match_operand:DI 0 "memory_operand" "+A") ;; memory + (match_operand:SIDITI 1 "register_operand" "r") ;; expected + (match_operand:SIDITI 2 "register_operand" "r") ;; desired + (match_operand:SI 3 "const_int_operand") ;; mod_s + (match_operand:SI 4 "const_int_operand")] ;; mod_f + UNSPEC_AMOCAS)] + "TARGET_ZACAS && TARGET_64BIT" + { + enum memmodel model_success = (enum memmodel) INTVAL (operands[3]); + enum memmodel model_failure = (enum memmodel) INTVAL (operands[4]); + enum memmodel model = riscv_union_memmodels (model_success, model_failure); + + if (model == MEMMODEL_SEQ_CST || model == MEMMODEL_ACQ_REL) + return "amocas..aqrl\t%1,%2,%0"; + else if (model == MEMMODEL_ACQUIRE) + return "amocas..aq\t%1,%2,%0"; + else if (model == MEMMODEL_RELEASE) + return "amocas..rl\t%1,%2,%0"; + else + return "amocas.\t%1,%2,%0"; + } + [(set_attr "type" "zacas")]) diff --git a/gcc/testsuite/gcc.target/riscv/zacas128.c b/gcc/testsuite/gcc.target/riscv/zacas128.c new file mode 100644 index 00000000000..0811effc4ea --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zacas128.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64g_zacas -mabi=lp64d" } */ + +int var; + +void foo1(void *mem, __int128 old, __int128 new) +{ + __builtin_riscv_amocas128(0, old, new, __ATOMIC_RELAXED, __ATOMIC_RELAXED); + __builtin_riscv_amocas128(&var, old, new, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); + __builtin_riscv_amocas128((void *)0x111, old, new, __ATOMIC_RELAXED, __ATOMIC_RELEASE); + __builtin_riscv_amocas128(mem, old, new, __ATOMIC_ACQUIRE, __ATOMIC_RELEASE); + __builtin_riscv_amocas128(mem, old, new, __ATOMIC_ACQ_REL, __ATOMIC_ACQ_REL); + __builtin_riscv_amocas128(mem, old, new, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +} + +/* { dg-final { scan-assembler-times "amocas.q" 6 } } */ +/* { dg-final { scan-assembler-times "amocas.q.aq" 4 } } */ +/* { dg-final { scan-assembler-times "amocas.q.rl" 1 } } */ +/* { dg-final { scan-assembler-times "amocas.q.aqrl" 3 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zacas32.c b/gcc/testsuite/gcc.target/riscv/zacas32.c new file mode 100644 index 00000000000..61a6ef90322 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zacas32.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32g_zacas -mabi=ilp32" } */ + +int var; + +void foo1(void *mem, int old, int new) +{ + __builtin_riscv_amocas32(0, old, new, __ATOMIC_RELAXED, __ATOMIC_RELAXED); + __builtin_riscv_amocas32(&var, old, new, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); + __builtin_riscv_amocas32((void*)0x111, old, new, __ATOMIC_RELAXED, __ATOMIC_RELEASE); + __builtin_riscv_amocas32(mem, old, new, __ATOMIC_ACQUIRE, __ATOMIC_RELEASE); + __builtin_riscv_amocas32(mem, old, new, __ATOMIC_ACQ_REL, __ATOMIC_ACQ_REL); + __builtin_riscv_amocas32(mem, old, new, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +} + +void foo2(void *mem, long long old, long long new) +{ + __builtin_riscv_amocas64(0, old, new, __ATOMIC_RELAXED, __ATOMIC_RELAXED); + __builtin_riscv_amocas64(&var, old, new, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); + __builtin_riscv_amocas64((void*)0x111, old, new, __ATOMIC_RELAXED, __ATOMIC_RELEASE); + __builtin_riscv_amocas64(mem, old, new, __ATOMIC_ACQUIRE, __ATOMIC_RELEASE); + __builtin_riscv_amocas64(mem, old, new, __ATOMIC_ACQ_REL, __ATOMIC_ACQ_REL); + __builtin_riscv_amocas64(mem, old, new, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +} + +/* { dg-final { scan-assembler-times "amocas.w" 6 } } */ +/* { dg-final { scan-assembler-times "amocas.w.aq" 4 } } */ +/* { dg-final { scan-assembler-times "amocas.w.rl" 1 } } */ +/* { dg-final { scan-assembler-times "amocas.w.aqrl" 3 } } */ + +/* { dg-final { scan-assembler-times "amocas.d" 6 } } */ +/* { dg-final { scan-assembler-times "amocas.d.aq" 4 } } */ +/* { dg-final { scan-assembler-times "amocas.d.rl" 1 } } */ +/* { dg-final { scan-assembler-times "amocas.d.aqrl" 3 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zacas64.c b/gcc/testsuite/gcc.target/riscv/zacas64.c new file mode 100644 index 00000000000..5f898d3a9bf --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zacas64.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64g_zacas -mabi=lp64d" } */ + +int var; + +void foo1(void *mem, int old, int new) +{ + __builtin_riscv_amocas32(0, old, new, __ATOMIC_RELAXED, __ATOMIC_RELAXED); + __builtin_riscv_amocas32(&var, old, new, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); + __builtin_riscv_amocas32((void*)0x111, old, new, __ATOMIC_RELAXED, __ATOMIC_RELEASE); + __builtin_riscv_amocas32(mem, old, new, __ATOMIC_ACQUIRE, __ATOMIC_RELEASE); + __builtin_riscv_amocas32(mem, old, new, __ATOMIC_ACQ_REL, __ATOMIC_ACQ_REL); + __builtin_riscv_amocas32(mem, old, new, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +} + +void foo2(void *mem, long long old, long long new) +{ + __builtin_riscv_amocas64(0, old, new, __ATOMIC_RELAXED, __ATOMIC_RELAXED); + __builtin_riscv_amocas64(&var, old, new, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); + __builtin_riscv_amocas64((void*)0x111, old, new, __ATOMIC_RELAXED, __ATOMIC_RELEASE); + __builtin_riscv_amocas64(mem, old, new, __ATOMIC_ACQUIRE, __ATOMIC_RELEASE); + __builtin_riscv_amocas64(mem, old, new, __ATOMIC_ACQ_REL, __ATOMIC_ACQ_REL); + __builtin_riscv_amocas64(mem, old, new, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +} + +/* { dg-final { scan-assembler-times "amocas.w" 6 } } */ +/* { dg-final { scan-assembler-times "amocas.w.aq" 4 } } */ +/* { dg-final { scan-assembler-times "amocas.w.rl" 1 } } */ +/* { dg-final { scan-assembler-times "amocas.w.aqrl" 3 } } */ + +/* { dg-final { scan-assembler-times "amocas.d" 6 } } */ +/* { dg-final { scan-assembler-times "amocas.d.aq" 4 } } */ +/* { dg-final { scan-assembler-times "amocas.d.rl" 1 } } */ +/* { dg-final { scan-assembler-times "amocas.d.aqrl" 3 } } */ -- 2.34.1