v79 adds a ":nt" non-temporal cache-locality hint to the post-increment store family and to dcfetch/dczeroa.
None of the ":nt" mnemonics are accepted by the assembler yet, so the new test embeds them via .word. Reviewed-by: Marco Liebel <[email protected]> Signed-off-by: Brian Cain <[email protected]> --- target/hexagon/attribs_def.h.inc | 2 + tests/tcg/hexagon/check_rev_gating.c | 32 +++++- tests/tcg/hexagon/v79_scalar.c | 157 ++++++++++++++++++++++++++ target/hexagon/tag_rev_info.c.inc | 23 ++++ target/hexagon/imported/encode_pp.def | 19 ++++ target/hexagon/imported/ldst.idef | 21 ++++ target/hexagon/imported/system.idef | 2 + tests/tcg/hexagon/meson.build | 1 + 8 files changed, 251 insertions(+), 6 deletions(-) create mode 100644 tests/tcg/hexagon/v79_scalar.c diff --git a/target/hexagon/attribs_def.h.inc b/target/hexagon/attribs_def.h.inc index d12f6ac4b1a..8b4eb27d682 100644 --- a/target/hexagon/attribs_def.h.inc +++ b/target/hexagon/attribs_def.h.inc @@ -21,6 +21,8 @@ DEF_ATTRIB(AA_DUMMY, "Dummy Zeroth Attribute", "", "") /* Misc */ DEF_ATTRIB(EXTENSION, "Extension instruction", "", "") +DEF_ATTRIB(NA_NT, "Non-Allocating Non-Temporal instruction", "", "") + DEF_ATTRIB(PRIV, "Not available in user or guest mode", "", "") DEF_ATTRIB(GUEST, "Not available in user mode", "", "") diff --git a/tests/tcg/hexagon/check_rev_gating.c b/tests/tcg/hexagon/check_rev_gating.c index d5295bf24ab..3f48ab9cd35 100644 --- a/tests/tcg/hexagon/check_rev_gating.c +++ b/tests/tcg/hexagon/check_rev_gating.c @@ -3,12 +3,15 @@ * are rejected with SIGILL. * * Compiled with -mv66 so that e_flags selects CPU v66. The test embeds - * instructions from v68 through v73 via .word encoding: the assembler - * enforces the selected CPU's own minimum version, so none of these -- - * including ones it otherwise knows how to assemble at their own - * target, such as callrh or unpause -- can be written as themselves in - * a file built for v66. The revision-gated decoder must reject every - * one of them, and linux-user must deliver SIGILL. + * instructions from v68 up through v79 via .word encoding: the + * assembler enforces the selected CPU's own minimum version, so none + * of these -- including ones it otherwise knows how to assemble at + * their own target, such as callrh or unpause -- can be written as + * themselves in a file built for v66. The v79 non-temporal hints + * (":nt") aren't known to the assembler at any target yet, so those + * would need .word regardless. The revision-gated decoder must reject + * representative instructions from each family, and linux-user must + * deliver SIGILL. * * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. * SPDX-License-Identifier: GPL-2.0-or-later @@ -108,6 +111,17 @@ TRY_FUNC(v73_jumprh, TRY_FUNC(v73_unpause, ".word 0x57e0d000 /* unpause */\n") +TRY_FUNC(v79_storeri_pi_nt, + ".word 0xaa82c308 /* memw(r2++#4):nt = r3 */\n") +TRY_FUNC(v79_pstorerit_pi_nt, + ".word 0xaa82e308 /* if (p0) memw(r2++#4):nt = r3 */\n") +TRY_FUNC(v79_pstorerif_pi_nt, + ".word 0xaa82e30c /* if (!p0) memw(r2++#4):nt = r3 */\n") +TRY_FUNC(v79_dczeroa_nt, + ".word 0xa0c2e000 /* dczeroa(r2):nt */\n") +TRY_FUNC(v79_dcfetchbo_nt, + ".word 0x9402e000 /* dcfetch(r2+#0):nt */\n") + int main(void) { struct sigaction act; @@ -140,6 +154,12 @@ int main(void) assert(try_v73_jumprh() == SIGILL); assert(try_v73_unpause() == SIGILL); + assert(try_v79_storeri_pi_nt() == SIGILL); + assert(try_v79_pstorerit_pi_nt() == SIGILL); + assert(try_v79_pstorerif_pi_nt() == SIGILL); + assert(try_v79_dczeroa_nt() == SIGILL); + assert(try_v79_dcfetchbo_nt() == SIGILL); + assert(signals_handled == expected_signals); puts("PASS"); diff --git a/tests/tcg/hexagon/v79_scalar.c b/tests/tcg/hexagon/v79_scalar.c new file mode 100644 index 00000000000..81eb277b739 --- /dev/null +++ b/tests/tcg/hexagon/v79_scalar.c @@ -0,0 +1,157 @@ +/* + * Test the scalar core instructions that are new in v79. + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <stdio.h> +#include <stdint.h> +#include <string.h> + +int err; + +static void __check32(int line, uint32_t result, uint32_t expect) +{ + if (result != expect) { + printf("ERROR at line %d: 0x%08x != 0x%08x\n", line, result, expect); + err++; + } +} + +#define check32(RES, EXP) __check32(__LINE__, RES, EXP) + +static uint32_t sbuf[4]; +static uint32_t newp; + +/* S2_storeri_pi_nt: memw(Rx32++#4):nt = Rt32 */ +static void test_storeri_pi_nt(void) +{ + uint32_t *p = sbuf; + + memset(sbuf, 0xff, sizeof(sbuf)); + asm volatile( + "r2 = %1\n\t" + "r3 = #0x12345678\n\t" + ".word 0xaa82c308\n\t" /* memw(r2++#4):nt = r3 */ + "r5 = ##newp\n\t" + "memw(r5 + #0) = r2\n\t" + : "+m"(newp) + : "r"(p) + : "r2", "r3", "r5", "memory"); + check32(sbuf[0], 0x12345678); + check32(newp, (uint32_t)(uintptr_t)(sbuf + 1)); +} + +static uint8_t bbuf[4]; + +/* S2_storerb_pi_nt: memb(Rx32++#1):nt = Rt32 */ +static void test_storerb_pi_nt(void) +{ + uint32_t *p = (uint32_t *)bbuf; + + memset(bbuf, 0xff, sizeof(bbuf)); + asm volatile( + "r2 = %1\n\t" + "r3 = #0x42\n\t" + ".word 0xaa02c308\n\t" /* memb(r2++#1):nt = r3 */ + "r5 = ##newp\n\t" + "memw(r5 + #0) = r2\n\t" + : "+m"(newp) + : "r"(p) + : "r2", "r3", "r5", "memory"); + check32(bbuf[0], 0x42); + check32(newp, (uint32_t)(uintptr_t)(bbuf + 1)); +} + +/* S2_pstorerit_pi_nt: if (Pv4) memw(Rx32++#4):nt = Rt32, predicate true */ +static void test_pstorerit_pi_nt(void) +{ + uint32_t *p = sbuf; + + memset(sbuf, 0xff, sizeof(sbuf)); + asm volatile( + "p0 = cmp.eq(r0, r0)\n\t" /* P0 = true */ + "r2 = %1\n\t" + "r3 = #0x11223344\n\t" + ".word 0xaa82e308\n\t" /* if (p0) memw(r2++#4):nt = r3 */ + "r5 = ##newp\n\t" + "memw(r5 + #0) = r2\n\t" + : "+m"(newp) + : "r"(p) + : "r0", "r2", "r3", "r5", "p0", "memory"); + check32(sbuf[0], 0x11223344); + check32(newp, (uint32_t)(uintptr_t)(sbuf + 1)); +} + +/* S2_pstorerif_pi_nt: if (!Pv4) memw(Rx32++#4):nt = Rt32, predicate false */ +static void test_pstorerif_pi_nt(void) +{ + uint32_t *p = sbuf; + + memset(sbuf, 0xff, sizeof(sbuf)); + asm volatile( + "r0 = #1\n\t" + "r1 = #2\n\t" + "p0 = cmp.eq(r0, r1)\n\t" /* P0 = false */ + "r2 = %1\n\t" + "r3 = #0x99887766\n\t" + ".word 0xaa82e30c\n\t" /* if (!p0) memw(r2++#4):nt = r3 */ + "r5 = ##newp\n\t" + "memw(r5 + #0) = r2\n\t" + : "+m"(newp) + : "r"(p) + : "r0", "r1", "r2", "r3", "r5", "p0", "memory"); + check32(sbuf[0], 0x99887766); + check32(newp, (uint32_t)(uintptr_t)(sbuf + 1)); +} + +/* Y2_dczeroa_nt: dczeroa(Rs32):nt -- zeroes a 32-byte cacheline */ +static uint8_t cz[64] __attribute__((aligned(32))); + +static void test_dczeroa_nt(void) +{ + memset(cz, 0xaa, sizeof(cz)); + asm volatile( + "r2 = %1\n\t" + ".word 0xa0c2e000\n\t" /* dczeroa(r2):nt */ + : "+m"(cz) + : "r"(cz) + : "r2", "memory"); + for (int i = 0; i < 32; i++) { + check32(cz[i], 0); + } + for (int i = 32; i < 64; i++) { + check32(cz[i], 0xaa); + } +} + +/* Y2_dcfetchbo_nt: dcfetch(Rs32+#0):nt -- a hint, must not fault or store */ +static uint8_t df[32] __attribute__((aligned(8))); + +static void test_dcfetchbo_nt(void) +{ + memset(df, 0x55, sizeof(df)); + asm volatile( + "r2 = %1\n\t" + ".word 0x9402e000\n\t" /* dcfetch(r2+#0):nt */ + : "+m"(df) + : "r"(df) + : "r2", "memory"); + for (int i = 0; i < 32; i++) { + check32(df[i], 0x55); + } +} + +int main() +{ + test_storeri_pi_nt(); + test_storerb_pi_nt(); + test_pstorerit_pi_nt(); + test_pstorerif_pi_nt(); + test_dczeroa_nt(); + test_dcfetchbo_nt(); + + puts(err ? "FAIL" : "PASS"); + return err ? 1 : 0; +} diff --git a/target/hexagon/tag_rev_info.c.inc b/target/hexagon/tag_rev_info.c.inc index 44513f46809..48bdc52bfdb 100644 --- a/target/hexagon/tag_rev_info.c.inc +++ b/target/hexagon/tag_rev_info.c.inc @@ -619,6 +619,29 @@ static const struct tag_rev_info tag_rev_info[XX_LAST_OPCODE] = { [V6_vassign_tmp] = { .introduced = HEX_VER_V69, .removed = HEX_VER_NONE }, [V6_vcombine_tmp] = { .introduced = HEX_VER_V69, .removed = HEX_VER_NONE }, [V6_vmpyuhvs] = { .introduced = HEX_VER_V69, .removed = HEX_VER_NONE }, + + [S2_pstorerbf_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerbt_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerdf_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerdt_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerhf_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerht_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerif_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerit_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_storerb_pi_nt] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE }, + [S2_storerd_pi_nt] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE }, + [S2_storerh_pi_nt] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE }, + [S2_storeri_pi_nt] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE }, + [Y2_dcfetchbo_nt] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE }, + [Y2_dczeroa_nt] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE }, }; #endif /* HEXAGON_TAG_ARCH_TABLE_H */ diff --git a/target/hexagon/imported/encode_pp.def b/target/hexagon/imported/encode_pp.def index 1fce318b2bb..fca8f8aeb1a 100644 --- a/target/hexagon/imported/encode_pp.def +++ b/target/hexagon/imported/encode_pp.def @@ -407,6 +407,7 @@ DEF_ENC32(R6_release_st_vi, ICLASS_ST" 000 01 11sssss PP0ttttt --1011dd") DEF_EXT_SPACE(EXTRACTW, ICLASS_LD" 001 0 000 iiiii PP0iiiii 001iiiii") DEF_ENC32(Y2_dcfetchbo, ICLASS_LD" 010 0 000 sssss PP0--iii iiiiiiii") +DEF_ENC32(Y2_dcfetchbo_nt,"10010100000sssssPP10-iiiiiiiiiii") @@ -473,6 +474,13 @@ STD_ST_ENC(rbnew, "1 101","00ttt") STD_ST_ENC(rhnew, "1 101","01ttt") STD_ST_ENC(rinew, "1 101","10ttt") +/* Non-temporal post-increment stores: the OPC nibble's high bit, always + * 1 above, is repurposed as the "nt" hint for this addressing mode only. */ +DEF_ENC32(S2_storerb_pi_nt,"10101010000xxxxxPP0ttttt0iiii-0-") +DEF_ENC32(S2_storerh_pi_nt,"10101010010xxxxxPP0ttttt0iiii-0-") +DEF_ENC32(S2_storeri_pi_nt,"10101010100xxxxxPP0ttttt0iiii-0-") +DEF_ENC32(S2_storerd_pi_nt,"10101010110xxxxxPP0ttttt0iiii-00") + STD_PST_ENC(rb, "1 000","ttttt") STD_PST_ENC(rh, "1 010","ttttt") STD_PST_ENC(rf, "1 011","ttttt") @@ -482,6 +490,16 @@ STD_PST_ENC(rbnew, "1 101","00ttt") STD_PST_ENC(rhnew, "1 101","01ttt") STD_PST_ENC(rinew, "1 101","10ttt") +/* Predicated forms of the non-temporal post-increment stores above. */ +DEF_ENC32(S2_pstorerbt_pi_nt,"10101010000xxxxxPP1ttttt0iiii0vv") +DEF_ENC32(S2_pstorerbf_pi_nt,"10101010000xxxxxPP1ttttt0iiii1vv") +DEF_ENC32(S2_pstorerht_pi_nt,"10101010010xxxxxPP1ttttt0iiii0vv") +DEF_ENC32(S2_pstorerhf_pi_nt,"10101010010xxxxxPP1ttttt0iiii1vv") +DEF_ENC32(S2_pstorerit_pi_nt,"10101010100xxxxxPP1ttttt0iiii0vv") +DEF_ENC32(S2_pstorerif_pi_nt,"10101010100xxxxxPP1ttttt0iiii1vv") +DEF_ENC32(S2_pstorerdt_pi_nt,"10101010110xxxxxPP1ttttt0iiii0vv") +DEF_ENC32(S2_pstorerdf_pi_nt,"10101010110xxxxxPP1ttttt0iiii1vv") + /* User */ @@ -492,6 +510,7 @@ STD_PST_ENC(rinew, "1 101","10ttt") DEF_ENC32(S2_allocframe, ICLASS_ST" 000 01 00xxxxx PP000iii iiiiiiii") DEF_ENC32(Y5_l2locka, ICLASS_ST" 000 01 11sssss PP1----- ------dd") DEF_ENC32(Y2_dczeroa, ICLASS_ST" 000 01 10sssss PP0----- --------") +DEF_ENC32(Y2_dczeroa_nt,"10100000110sssssPP1-------------") DEF_ENC32(Y2_barrier, ICLASS_ST" 100 00 00----- PP------ 000-----") diff --git a/target/hexagon/imported/ldst.idef b/target/hexagon/imported/ldst.idef index 4e1e5d5326d..7106a0c572c 100644 --- a/target/hexagon/imported/ldst.idef +++ b/target/hexagon/imported/ldst.idef @@ -118,6 +118,16 @@ STD_ST_AMODES(storerh, "Rt32", "memh","Store Half integer",ATTRIBS(A_REGWRSIZE_2 STD_ST_AMODES(storerf, "Rt.H32", "memh","Store Upper Half integer",ATTRIBS(A_REGWRSIZE_2B,A_MEMSIZE_2B,A_STORE),"1",fSTORE(1,2,EA,fGETHALF(1,RtV)),1) STD_ST_AMODES(storeri, "Rt32", "memw","Store Word",ATTRIBS(A_REGWRSIZE_4B,A_MEMSIZE_4B,A_STORE),"2",fSTORE(1,4,EA,RtV),2) STD_ST_AMODES(storerd, "Rtt32","memd","Store Double integer",ATTRIBS(A_REGWRSIZE_8B,A_MEMSIZE_8B,A_STORE),"3",fSTORE(1,8,EA,RttV),3) + +/* + * Non-temporal post-increment stores: same store, with a cache-locality + * hint that a normal-priority cache line is unlikely to be reused soon. + */ +Q6INSN(S2_storerb_pi_nt,"memb(Rx32++#s4:0):nt=Rt32",ATTRIBS(A_ARCHV2,A_MEMSIZE_1B,A_STORE,A_NA_NT),"Store Byte",{fEA_REG(RxV); fPM_I(RxV,siV); fSTORE(1,1,EA,fGETBYTE(0,RtV)); }) +Q6INSN(S2_storerh_pi_nt,"memh(Rx32++#s4:1):nt=Rt32",ATTRIBS(A_REGWRSIZE_2B,A_ARCHV2,A_MEMSIZE_2B,A_STORE,A_NA_NT),"Store Half integer",{fEA_REG(RxV); fPM_I(RxV,siV); fSTORE(1,2,EA,fGETHALF(0,RtV)); }) +Q6INSN(S2_storeri_pi_nt,"memw(Rx32++#s4:2):nt=Rt32",ATTRIBS(A_REGWRSIZE_4B,A_ARCHV2,A_MEMSIZE_4B,A_STORE,A_NA_NT),"Store Word",{fEA_REG(RxV); fPM_I(RxV,siV); fSTORE(1,4,EA,RtV); }) +Q6INSN(S2_storerd_pi_nt,"memd(Rx32++#s4:3):nt=Rtt32",ATTRIBS(A_REGWRSIZE_8B,A_ARCHV2,A_MEMSIZE_8B,A_STORE,A_NA_NT),"Store Double integer",{fEA_REG(RxV); fPM_I(RxV,siV); fSTORE(1,8,EA,RttV); }) + STD_ST_AMODES(storerinew, "Nt8.new", "memw","Store Word",ATTRIBS(A_REGWRSIZE_4B,A_NOTE_NEWVAL_SLOT0,A_NVSTORE,A_NOTE_NVSLOT0,A_MEMSIZE_4B,A_STORE,A_RESTRICT_NOSLOT1_STORE),"2",fSTORE(1,4,EA,fNEWREG_ST(NtN)),2) STD_ST_AMODES(storerbnew, "Nt8.new", "memb","Store Byte",ATTRIBS(A_NOTE_NEWVAL_SLOT0,A_NVSTORE,A_NOTE_NVSLOT0,A_MEMSIZE_1B,A_STORE,A_RESTRICT_NOSLOT1_STORE),"0",fSTORE(1,1,EA,fGETBYTE(0,fNEWREG_ST(NtN))),0) STD_ST_AMODES(storerhnew, "Nt8.new", "memh","Store Half integer",ATTRIBS(A_REGWRSIZE_2B,A_NOTE_NEWVAL_SLOT0,A_NVSTORE,A_NOTE_NVSLOT0,A_MEMSIZE_2B,A_STORE,A_RESTRICT_NOSLOT1_STORE),"1",fSTORE(1,2,EA,fGETHALF(0,fNEWREG_ST(NtN))),1) @@ -277,6 +287,17 @@ STD_PST_AMODES(storerh,"Rt32","memh","Store Half integer",ATTRIBS(A_REGWRSIZE_2B STD_PST_AMODES(storerf,"Rt.H32","memh","Store Upper Half integer",ATTRIBS(A_REGWRSIZE_2B,A_ARCHV2,A_MEMSIZE_2B,A_STORE),"1",1,fSTORE(1,2,EA,fGETHALF(1,RtV))) STD_PST_AMODES(storeri,"Rt32","memw","Store Word",ATTRIBS(A_REGWRSIZE_4B,A_ARCHV2,A_MEMSIZE_4B,A_STORE),"2",2,fSTORE(1,4,EA,RtV)) STD_PST_AMODES(storerd,"Rtt32","memd","Store Double integer",ATTRIBS(A_REGWRSIZE_8B,A_ARCHV2,A_MEMSIZE_8B,A_STORE),"3",3,fSTORE(1,8,EA,RttV)) + +/* Predicated forms of the non-temporal post-increment stores above. */ +Q6INSN(S2_pstorerbt_pi_nt,"if (Pv4) memb(Rx32++#s4:0):nt=Rt32",ATTRIBS(A_ARCHV2,A_MEMSIZE_1B,A_STORE,A_NA_NT),"Store Byte",{fEA_REG(RxV); if (fLSBOLD(PvV)){ fPM_I(RxV,siV); fSTORE(1,1,EA,fGETBYTE(0,RtV));} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerbf_pi_nt,"if (!Pv4) memb(Rx32++#s4:0):nt=Rt32",ATTRIBS(A_ARCHV2,A_MEMSIZE_1B,A_STORE,A_NA_NT),"Store Byte",{fEA_REG(RxV); if (fLSBOLDNOT(PvV)){ fPM_I(RxV,siV); fSTORE(1,1,EA,fGETBYTE(0,RtV));} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerht_pi_nt,"if (Pv4) memh(Rx32++#s4:1):nt=Rt32",ATTRIBS(A_REGWRSIZE_2B,A_ARCHV2,A_MEMSIZE_2B,A_STORE,A_NA_NT),"Store Half integer",{fEA_REG(RxV); if (fLSBOLD(PvV)){ fPM_I(RxV,siV); fSTORE(1,2,EA,fGETHALF(0,RtV));} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerhf_pi_nt,"if (!Pv4) memh(Rx32++#s4:1):nt=Rt32",ATTRIBS(A_REGWRSIZE_2B,A_ARCHV2,A_MEMSIZE_2B,A_STORE,A_NA_NT),"Store Half integer",{fEA_REG(RxV); if (fLSBOLDNOT(PvV)){ fPM_I(RxV,siV); fSTORE(1,2,EA,fGETHALF(0,RtV));} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerit_pi_nt,"if (Pv4) memw(Rx32++#s4:2):nt=Rt32",ATTRIBS(A_REGWRSIZE_4B,A_ARCHV2,A_MEMSIZE_4B,A_STORE,A_NA_NT),"Store Word",{fEA_REG(RxV); if (fLSBOLD(PvV)){ fPM_I(RxV,siV); fSTORE(1,4,EA,RtV);} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerif_pi_nt,"if (!Pv4) memw(Rx32++#s4:2):nt=Rt32",ATTRIBS(A_REGWRSIZE_4B,A_ARCHV2,A_MEMSIZE_4B,A_STORE,A_NA_NT),"Store Word",{fEA_REG(RxV); if (fLSBOLDNOT(PvV)){ fPM_I(RxV,siV); fSTORE(1,4,EA,RtV);} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerdt_pi_nt,"if (Pv4) memd(Rx32++#s4:3):nt=Rtt32",ATTRIBS(A_REGWRSIZE_8B,A_ARCHV2,A_MEMSIZE_8B,A_STORE,A_NA_NT),"Store Double integer",{fEA_REG(RxV); if (fLSBOLD(PvV)){ fPM_I(RxV,siV); fSTORE(1,8,EA,RttV);} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerdf_pi_nt,"if (!Pv4) memd(Rx32++#s4:3):nt=Rtt32",ATTRIBS(A_REGWRSIZE_8B,A_ARCHV2,A_MEMSIZE_8B,A_STORE,A_NA_NT),"Store Double integer",{fEA_REG(RxV); if (fLSBOLDNOT(PvV)){ fPM_I(RxV,siV); fSTORE(1,8,EA,RttV);} else {STORE_CANCEL(EA);}}) + STD_PST_AMODES(storerinew,"Nt8.new","memw","Store Word",ATTRIBS(A_REGWRSIZE_4B,A_ARCHV2,A_NOTE_NEWVAL_SLOT0,A_NVSTORE,A_NOTE_NVSLOT0,A_MEMSIZE_4B,A_STORE,A_RESTRICT_NOSLOT1_STORE),"2",2,fSTORE(1,4,EA,fNEWREG_ST(NtN))) STD_PST_AMODES(storerbnew,"Nt8.new","memb","Store Byte",ATTRIBS(A_ARCHV2,A_NOTE_NEWVAL_SLOT0,A_NVSTORE,A_NOTE_NVSLOT0,A_MEMSIZE_1B,A_STORE,A_RESTRICT_NOSLOT1_STORE),"0",0,fSTORE(1,1,EA,fGETBYTE(0,fNEWREG_ST(NtN)))) STD_PST_AMODES(storerhnew,"Nt8.new","memh","Store Half integer",ATTRIBS(A_REGWRSIZE_2B,A_ARCHV2,A_NOTE_NEWVAL_SLOT0,A_NVSTORE,A_NOTE_NVSLOT0,A_MEMSIZE_2B,A_STORE,A_RESTRICT_NOSLOT1_STORE),"1",1,fSTORE(1,2,EA,fGETHALF(0,fNEWREG_ST(NtN)))) diff --git a/target/hexagon/imported/system.idef b/target/hexagon/imported/system.idef index b44e87565c3..6187ada5abb 100644 --- a/target/hexagon/imported/system.idef +++ b/target/hexagon/imported/system.idef @@ -238,10 +238,12 @@ Q6INSN(Y6_dmresume,"dmresume(Rs32)",ATTRIBS(A_NOTE_NOPACKET,A_RESTRICT_NOPACKET, Q6INSN(Y2_dcfetchbo,"dcfetch(Rs32+#u11:3)",ATTRIBS(A_RESTRICT_PREFERSLOT0,A_DCFETCH,A_RESTRICT_NOSLOT1_STORE),"Data Cache Prefetch",{fEA_RI(RsV,uiV); fDCFETCH(EA);}) +Q6INSN(Y2_dcfetchbo_nt,"dcfetch(Rs32+#u11:3):nt",ATTRIBS(A_NA_NT,A_RESTRICT_PREFERSLOT0,A_DCFETCH,A_RESTRICT_NOSLOT1_STORE),"Data Cache Prefetch",{fEA_RI(RsV,uiV); fDCFETCH(EA);}) Q6INSN(Y2_dckill,"dckill",ATTRIBS(A_PRIV,A_NOTE_PRIV,A_NOTE_NOPACKET,A_RESTRICT_SLOT0ONLY,A_RESTRICT_NOPACKET,A_CACHEOP,A_DCFLUSHOP),"Data Cache Invalidate",{fDCKILL();}) Q6INSN(Y2_dczeroa,"dczeroa(Rs32)",ATTRIBS(A_STORE,A_RESTRICT_SLOT1_AOK,A_NOTE_SLOT1_AOK,A_RESTRICT_SLOT0ONLY,A_CACHEOP,A_COPBYADDRESS,A_DCZEROA),"Zero an aligned 32-byte cacheline",{fEA_REG(RsV); fDCZEROA(EA);}) +Q6INSN(Y2_dczeroa_nt,"dczeroa(Rs32):nt",ATTRIBS(A_STORE,A_RESTRICT_SLOT1_AOK,A_NOTE_SLOT1_AOK,A_RESTRICT_SLOT0ONLY,A_CACHEOP,A_COPBYADDRESS,A_DCZEROA,A_NA_NT),"Zero an aligned 32-byte cacheline",{fEA_REG(RsV); fDCZEROA(EA);}) Q6INSN(Y2_dccleana,"dccleana(Rs32)",ATTRIBS(A_RESTRICT_SLOT1_AOK,A_NOTE_SLOT1_AOK,A_RESTRICT_SLOT0ONLY,A_CACHEOP,A_COPBYADDRESS,A_DCFLUSHOP),"Data Cache Clean Address",{fEA_REG(RsV); fDCCLEANA(EA);}) Q6INSN(Y2_dccleanidx,"dccleanidx(Rs32)",ATTRIBS(A_PRIV,A_NOTE_PRIV,A_RESTRICT_PACKET_AXOK,A_NOTE_AXOK,A_RESTRICT_SLOT0ONLY,A_CACHEOP,A_COPBYIDX,A_DCFLUSHOP),"Data Cache Clean Index",{fDCCLEANIDX(RsV);}) Q6INSN(Y2_dccleaninva,"dccleaninva(Rs32)",ATTRIBS(A_RESTRICT_SLOT1_AOK,A_NOTE_SLOT1_AOK,A_RESTRICT_SLOT0ONLY,A_CACHEOP,A_COPBYADDRESS,A_DCFLUSHOP),"Data Cache Clean and Invalidate Address",{fEA_REG(RsV); fDCCLEANINVA(EA);}) diff --git a/tests/tcg/hexagon/meson.build b/tests/tcg/hexagon/meson.build index 4a2826c4276..6e36a9a1220 100644 --- a/tests/tcg/hexagon/meson.build +++ b/tests/tcg/hexagon/meson.build @@ -101,6 +101,7 @@ tests += { 'v68_hvx.c': {'cflags': [cflags, '-mhvx', '-Wno-unused-function', '-mv68']}, 'v69_hvx.c': {'cflags': [cflags, '-mhvx', '-Wno-unused-function', '-mv69']}, 'v73_scalar.c': {'cflags': [cflags, '-Wno-unused-function', '-mv73']}, + 'v79_scalar.c': {'cflags': [cflags, '-Wno-unused-function', '-mv79']}, 'valid-slots.c': {'cflags': cflags}, 'vector_add_int.c': {'cflags': [cflags, '-mhvx', '-fvectorize']}, } -- 2.34.1
