diff options
Diffstat (limited to 'tests/tcg/hexagon/dual_stores.c')
-rw-r--r-- | tests/tcg/hexagon/dual_stores.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/tests/tcg/hexagon/dual_stores.c b/tests/tcg/hexagon/dual_stores.c new file mode 100644 index 000000000..a86a381ab --- /dev/null +++ b/tests/tcg/hexagon/dual_stores.c @@ -0,0 +1,60 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> + +/* + * Make sure that two stores in the same packet honor proper + * semantics: slot 1 executes first, then slot 0. + * This is important when the addresses overlap. + */ +static inline void dual_stores(int *p, char *q, int x, char y) +{ + asm volatile("{\n\t" + " memw(%0) = %2\n\t" + " memb(%1) = %3\n\t" + "}\n" + :: "r"(p), "r"(q), "r"(x), "r"(y) + : "memory"); +} + +typedef union { + int word; + char byte; +} Dual; + +int err; + +static void check(Dual d, int expect) +{ + if (d.word != expect) { + printf("ERROR: 0x%08x != 0x%08x\n", d.word, expect); + err++; + } +} + +int main() +{ + Dual d; + + d.word = ~0; + dual_stores(&d.word, &d.byte, 0x12345678, 0xff); + check(d, 0x123456ff); + + puts(err ? "FAIL" : "PASS"); + return err; +} |