[AFMOVW]= {SizeW | LeftAddr | RightWrite},
[AFMOVV]= {SizeQ | LeftAddr | RightWrite},
- [AFMOVDP]= {SizeD | LeftRead | RightAddr},
- [AFMOVFP]= {SizeF | LeftRead | RightAddr},
- [AFMOVLP]= {SizeL | LeftRead | RightAddr},
- [AFMOVWP]= {SizeW | LeftRead | RightAddr},
- [AFMOVVP]= {SizeQ | LeftRead | RightAddr},
+ // These instructions are marked as RightAddr
+ // so that the register optimizer does not try to replace the
+ // memory references with integer register references.
+ // But they do not use the previous value at the address, so
+ // we also mark them RightWrite.
+ [AFMOVDP]= {SizeD | LeftRead | RightWrite | RightAddr},
+ [AFMOVFP]= {SizeF | LeftRead | RightWrite | RightAddr},
+ [AFMOVLP]= {SizeL | LeftRead | RightWrite | RightAddr},
+ [AFMOVWP]= {SizeW | LeftRead | RightWrite | RightAddr},
+ [AFMOVVP]= {SizeQ | LeftRead | RightWrite | RightAddr},
[AFMULD]= {SizeD | LeftAddr | RightRdwr},
[AFMULDP]= {SizeD | LeftAddr | RightRdwr},
if(prog->as == AVARDEF || prog->as == AVARKILL)
bvset(varkill, pos);
} else {
- if(info.flags & (RightRead | RightAddr))
+ // RightRead is a read, obviously.
+ // RightAddr by itself is also implicitly a read.
+ //
+ // RightAddr|RightWrite means that the address is being taken
+ // but only so that the instruction can write to the value.
+ // It is not a read. It is equivalent to RightWrite except that
+ // having the RightAddr bit set keeps the registerizer from
+ // trying to substitute a register for the memory location.
+ if((info.flags & RightRead) || (info.flags & (RightAddr|RightWrite)) == RightAddr)
bvset(uevar, pos);
if(info.flags & RightWrite)
if(to->node != nil && (!isfat(to->node->type) || prog->as == AVARDEF))