aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/gcc/testsuite/gcc.target/i386/pr57046.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8/gcc/testsuite/gcc.target/i386/pr57046.c')
-rw-r--r--gcc-4.8/gcc/testsuite/gcc.target/i386/pr57046.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/gcc-4.8/gcc/testsuite/gcc.target/i386/pr57046.c b/gcc-4.8/gcc/testsuite/gcc.target/i386/pr57046.c
new file mode 100644
index 000000000..0aa43f9df
--- /dev/null
+++ b/gcc-4.8/gcc/testsuite/gcc.target/i386/pr57046.c
@@ -0,0 +1,77 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+struct emac {
+ unsigned reg[23];
+};
+
+struct mop {
+ unsigned long long addr;
+ unsigned int size;
+};
+
+unsigned int __attribute__((__noinline__))
+level(const struct emac *obj)
+{
+ return 0;
+}
+
+void __attribute__((__noinline__))
+info(struct emac *dev, unsigned long long addr)
+{
+ asm("" : : : "memory");
+}
+
+unsigned long long __attribute__((__noinline__))
+get_value(const struct mop *mop)
+{
+ return 0x1234567890abcdefull;
+}
+
+int __attribute__((__noinline__))
+emac_operation(struct emac *obj, struct mop *mop)
+{
+ unsigned long long addr = mop->addr;
+ int index = addr >> 2;
+ unsigned int value, old_value;
+
+ if (mop->size != 4)
+ return 0;
+
+ if (index >= 23) {
+ if (level(obj) >= 1)
+ info(obj, addr);
+ return 0;
+ }
+
+ value = get_value(mop);
+ old_value = obj->reg[index];
+
+ info(obj, 0);
+
+ switch (index) {
+ case 0:
+ obj->reg[0] = old_value;
+ break;
+ case 7:
+ case 8:
+ obj->reg[index] = value;
+ break;
+ }
+
+ return 0;
+}
+
+int main(void)
+{
+ struct emac e = { { 0 } };
+ struct mop mop = { 32, 4 };
+
+ e.reg[8] = 0xdeadbeef;
+ emac_operation(&e, &mop);
+
+ if (e.reg[8] != 0x90abcdef)
+ __builtin_abort();
+
+ return 0;
+}