anchor.diff:                   "enq issueQ entry cannot be MMIO");
           doAssert(!isValid(ld_depLdQDeq_enqIss[info.tag]) &&
                    !isValid(ld_depLdEx_enqIss[info.tag]) &&
  -                 !isValid(ld_depStQDeq_enqIss[info.tag]) &&
  -                 !isValid(ld_deqSBDeq_enqIss[info.tag]),
  +`ifndef TSO_MM
  +                 !isValid(ld_depSBDeq_enqIss[info.tag]) &&
  +`endif
  +                 !isValid(ld_depStQDeq_enqIss[info.tag]),
                    "enq issueQ entry cannot have dependency");
           doAssert(info.shiftedBE == ld_shiftedBE_enqIss[info.tag],
                    "BE should match");
           doAssert(info.paddr == ld_paddr_enqIss[info.tag],
                    "paddr should match");
           // enq to issueQ & change state (prevent enq this tag again)
  -        issueQ.enq(ToSpecFifo {
  +        issueLdQ.enq(ToSpecFifo {
               data: info,
               spec_bits: ld_specBits_enqIss[info.tag]
           });
  
positive.code:     // wakeupLdStalledBySB (Weak only) <
      // deqSt <
      // respLd <
      // updateDataBE <
      // enq <
      // correctSpec
  
      // Scheduling notes:
      // 1. getKilled, deqLd, validateSt are almost readonly, so put them at
      // beginning.
      // 2. A load can first updateAddr and then issue in one cycle (in two
      // rules), so updateAddr < issueLd.
      // 3. cacheEvict and updateAddr needs the readFrom fields in LQ, issueLd
      // needs the olderSt field and SQ. Since deqSt changeds SQ and readFrom and
      // olderSt fields of LQ, we put cacheEvict, updateAddr, issueLd < deqSt
      // 4. There should not be requirement between cachEvict and updateAddr,
      // just choose arbitrarily.
      // 5. Since load resp may be enq into a bypass fifo after coming out of the
      // cache, respLd should not precede the cache rule that sends resp. We just
      // put the cache resp rule < respLd. Since cache resp rule calls deqSt
      // (TSO) or wakeupLdStalledBySB (WEAK), we have deqSt < respLd and
      // wakeupLdStalledBySB < respLd.
      // 6. Since respLd needs shiftedBE, we put respLd < updateDataBE.
      // 7. There is a bypassing path from updateAddr to deqSt. This path does
      // not seem to be a problem.
      // 8. To cut off bypassing from stb.enq to stb.deq, we put wakeupStallBySB
      // < deqSt.
  
      // W.r.t wrongSpec:
      // getKillLd < wrongSpec (they fire in same rule)
  
negative.code: typedef Bit#(TSub#(AddrSz, TLog#(NumBytes))) DataAlignedAddr;
  function DataAlignedAddr getDataAlignedAddr(Addr a) = truncateLSB(a);
  
  // whether two memory accesses are to the same dword
  function Bool sameAlignedAddr(Addr a, Addr b);
      return getDataAlignedAddr(a) == getDataAlignedAddr(b);
  endfunction
  
  // whether two memory accesses overlap
  function Bool overlapAddr(Addr addr_1, ByteEn shift_be_1,
                            Addr addr_2, ByteEn shift_be_2);
      Bool be_overlap = (pack(shift_be_1) & pack(shift_be_2)) != 0;
      return be_overlap && sameAlignedAddr(addr_1, addr_2);
  endfunction
  
  // check shiftBE1 covers shiftBE2
  function Bool be1CoverBe2(ByteEn shift_be_1, ByteEn shift_be_2);
      return (pack(shift_be_1) & pack(shift_be_2)) == pack(shift_be_2);
  endfunction
  
  // check whether mem op addr is aligned w.r.t data size
  