1/* { dg-do run } */ 2/* { dg-options "-O2" } */ 3 4struct emac { 5 unsigned reg[23]; 6}; 7 8struct mop { 9 unsigned long long addr; 10 unsigned int size; 11}; 12 13unsigned int __attribute__((__noinline__)) 14level(const struct emac *obj) 15{ 16 return 0; 17} 18 19void __attribute__((__noinline__)) 20info(struct emac *dev, unsigned long long addr) 21{ 22 asm("" : : : "memory"); 23} 24 25unsigned long long __attribute__((__noinline__)) 26get_value(const struct mop *mop) 27{ 28 return 0x1234567890abcdefull; 29} 30 31int __attribute__((__noinline__)) 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 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