[PTLsim-devel] Possible bug with CMPXCHG8B

Matt T. Yourst
Fri Jun 15 17:24:06 EDT 2007


On Friday 15 June 2007 15:33, Matt T. Yourst wrote:
>
> > (Incidentally, I /do/ need the instruction, so I've been trying to
> > decode the decoder as it were to fix it.)
> >
> > Looking through the decoder confirms that.
> > Opcode 0F C7 /1 is not decoded properly, as the whole group 9 extension
> > (denoted by C7) is not decoded at all.
> > Another issue is that CPUID reports the CMPXCHG8B instruction as present,
> > as far as I can tell.
>
> Thanks for pointing this out. CMPXCHG8B/16B is not a very common
> instruction, especially in 64-bit code, so I'm not surprised we missed it.
> I'll implement it now - expect a patch later today.
>

Patch for CMPXCHG8B and CMPXCHG16B is below - just put it in 
decode-complex.cpp. I'll add this to the next release (which will be coming 
soon, to add full SSE3 support and various other new instructions).

  case 0x1c7: { // cmpxchg8b/cmpxchg16b
    DECODE(eform, rd, (rex.mode64) ? q_mode : d_mode);
    ra = rd;
    if (modrm.reg != 1) MakeInvalid(); // only cmpxchg8b/cmpxchg16b are valid
    if (rd.type != OPTYPE_MEM) MakeInvalid();

    int sizeincr = (rex.mode64) ? 8 : 4;
    int sizeshift = (rex.mode64) ? 3 : 2;
    EndOfDecode();

    // cmpxchg16b
    prefixes |= PFX_LOCK;
    if (memory_fence_if_locked(0)) break;
      
    /*

    Microcode:

    ld     t0 = [mem]
    ld     t1 = [mem+8]
    sub    t2 = t0,rax
    sub    t3 = t1,rdx
    andcc  t7,flags = t2,t3
    sel.eq t2 = t0,rbx,(t7)
    sel.eq t3 = t1,rcx,(t7)
    sel.eq rax = t0,rax,(t7)
    sel.eq rdx = t1,rdx,(t7)
    st     [mem],t2
    st     [mem+8],t3
    
    */
    
    operand_load(REG_temp0, ra, OP_ld);
    ra.mem.offset += sizeincr;
    operand_load(REG_temp1, ra, OP_ld);
    
    TransOp sublo(OP_sub, REG_temp2, REG_temp0, REG_rax, REG_zero, sizeshift, 
0, 0, FLAGS_DEFAULT_ALU); sublo.nouserflags = 1; this << sublo;
    TransOp subhi(OP_sub, REG_temp3, REG_temp1, REG_rdx, REG_zero, sizeshift, 
0, 0, FLAGS_DEFAULT_ALU); subhi.nouserflags = 1; this << subhi;
    this << TransOp(OP_andcc, REG_temp7, REG_temp2, REG_temp3, REG_zero, 
sizeshift, 0, 0, FLAGS_DEFAULT_ALU);
    { TransOp sel(OP_sel, REG_temp2, REG_temp0, REG_rbx, REG_temp7, 
sizeshift); sel.cond = COND_e; this << sel; }
    { TransOp sel(OP_sel, REG_temp3, REG_temp1, REG_rcx, REG_temp7, 
sizeshift); sel.cond = COND_e; this << sel; }
    { TransOp sel(OP_sel, REG_rax, REG_temp0, REG_rax, REG_temp7, sizeshift); 
sel.cond = COND_e; this << sel; }
    { TransOp sel(OP_sel, REG_rdx, REG_temp1, REG_rdx, REG_temp7, sizeshift); 
sel.cond = COND_e; this << sel; }
    result_store(REG_temp2, REG_temp4, rd);
    rd.mem.offset += sizeincr;
    result_store(REG_temp3, REG_temp5, rd);
    
    if (memory_fence_if_locked(1)) break;

    break;
  }

- Matt

-------------------------------------------------------
 Matt T. Yourst                    yourst at peptidal.com
 Peptidal Research Inc., Co-Founder and Lead Architect
-------------------------------------------------------


More information about the PTLsim-devel mailing list