Hi All,

We have some difficulty in understanding how the opt compiler generates machine
code (IA32) for "attemptWord".  We tried, but still got confused.

Take

attemptWord(obj, -8)

as an example.  obj is an object reference.

We printed out the machine codes the opt-compiler generated.  It is something like:

# ecx holds the obj reference
sub ecx, -8
CMPXCHG dword ptr [ecx], edx;         <- This is what we care about

We want to change the code generation for this "attemptWord" so that it will always
generate codes like this:

# ecx holds the obj reference
CMPXCHG dword ptr [ecx-8], edx;

However, we cannot find where the opt-compiler did this optimization.

--------
I listed what we found up to now.  We tracked parts of the code generation:

1. BC2HIR

if (methodName == VM_MagicNames.attemptWord) {
      OPT_Operand newVal = bc2ir.pop();
      OPT_Operand oldVal = bc2ir.pop();
      OPT_Operand offset = bc2ir.popAddress();
      OPT_Operand base = bc2ir.popRef();
      OPT_RegisterOperand test = gc.temps.makeTempInt();
      bc2ir.appendInstruction(Attempt.create(ATTEMPT_ADDR, test, base, offset, oldVal,
                                             newVal, null));
      bc2ir.push(test.copyD2U());
}

To our knowledge this generates the HIR inst for "attemptWord".  At this time the "base", "offset" are
still the correct ones.

2. LIRtoMIR

In LIRtoMIR stage 2, "Convert ALU operators", they changed all the other "ATTEMPT_*" into
"ATTEMPT_INT".  But this still didn't touch the offset/base.

There are many optimizations here.  One is BURS rules.

3. MIRtoMC

FinalMIRExpansion()

case IA32_LOCK_CMPXCHG_opcode:
    p.insertBefore(MIR_Empty.create(IA32_LOCK));
    p.operator=IA32_CMPXCHG ;
    break;

Add the IA32_LOCK before this cmpxchg.

4. Assembler

private void doCMPXCHG(OPT_Instruction inst) {
    // According to different addressing mode, generate different format of CMPXCHG.
    if (...) {
       ...
    } else {
              if (VM.VerifyAssertions && !isRegInd(MIR_CompareExchange.getMemAddr(inst))) VM._assert(false, inst.toString());
              if (VM.VerifyAssertions && !isReg(MIR_CompareExchange.getNewValue(inst))) VM._assert(false, inst.toString());
              emitCMPXCHG_RegInd_Reg(
                  getBase(MIR_CompareExchange.getMemAddr(inst)),               // This finally generates the inst pattern we don't want
                  getReg(MIR_CompareExchange.getNewValue(inst)));
            }
}

It seems somewhere before Assembler in opt-compiler they decide to generate the inst pattern using RegIdxReg mode.
But we failed to find the place.  Did this happen during the BURS MIR code generation?
--------

Thank you so much.

Yours,
Yan Tang