1 /* { dg-do run } */ 2 /* { dg-options "-O2" } */ 3 4 struct emac { 5 unsigned reg[23]; 6 }; 7 8 struct mop { 9 unsigned long long addr; 10 unsigned int size; 11 }; 12 13 unsigned int __attribute__((__noinline__)) level(const struct emac * obj)14level(const struct emac *obj) 15 { 16 return 0; 17 } 18 19 void __attribute__((__noinline__)) info(struct emac * dev,unsigned long long addr)20info(struct emac *dev, unsigned long long addr) 21 { 22 asm("" : : : "memory"); 23 } 24 25 unsigned long long __attribute__((__noinline__)) get_value(const struct mop * mop)26get_value(const struct mop *mop) 27 { 28 return 0x1234567890abcdefull; 29 } 30 31 int __attribute__((__noinline__)) emac_operation(struct emac * obj,struct mop * mop)32emac_operation(struct emac *obj, struct mop *mop) 33 { 34 unsigned long long addr = mop->addr; 35 int index = addr >> 2; 36 unsigned int value, old_value; 37 38 if (mop->size != 4) 39 return 0; 40 41 if (index >= 23) { 42 if (level(obj) >= 1) 43 info(obj, addr); 44 return 0; 45 } 46 47 value = get_value(mop); 48 old_value = obj->reg[index]; 49 50 info(obj, 0); 51 52 switch (index) { 53 case 0: 54 obj->reg[0] = old_value; 55 break; 56 case 7: 57 case 8: 58 obj->reg[index] = value; 59 break; 60 } 61 62 return 0; 63 } 64 main(void)65int main(void) 66 { 67 struct emac e = { { 0 } }; 68 struct mop mop = { 32, 4 }; 69 70 e.reg[8] = 0xdeadbeef; 71 emac_operation(&e, &mop); 72 73 if (e.reg[8] != 0x90abcdef) 74 __builtin_abort(); 75 76 return 0; 77 } 78