using SETcc instructions with compiler

22 views
Skip to first unread message

Palo Marton

unread,
Jan 14, 2014, 5:13:02 AM1/14/14
to asmji...@googlegroups.com
I want to use SETcc instructions to set GPD variable to 1/0 based on condition. In assembler it can be done with 2 instructions

MOV EAX,0
SETcc AL

How can I do same in compiler without using additional register? Trivial solution like this fails on ASMJIT_ASSERT, because of operand size:

AsmJit::GPVar fc(c.newGP(AsmJit::VARIABLE_TYPE_GPD));
c.mov(fc, 0);
c.setg(fc);

Palo

Petr Kobalíček

unread,
Jan 14, 2014, 5:17:59 AM1/14/14
to asmjit-dev
Hi Palo,

this is fixable in the following way:

AsmJit::GPVar fc(c.newGP(AsmJit::VARIABLE_TYPE_GPD));
c.mov(fc, 0);
c.setg(fc.r8Lo()); // or other method, I used asmjit trunk to get name of this one.

Cheers,
Petr

--
 
---
You received this message because you are subscribed to the Google Groups "asmjit-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to asmjit-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Palo Marton

unread,
Jan 14, 2014, 6:40:42 AM1/14/14
to asmji...@googlegroups.com
Thanks. It works... mostly... Sometimes it fails during translate of this instruction in allocGPVar:

    // Prevented variables can't be spilled. _getSpillCandidate() never returns
    // prevented variables, but when jumping to L_spill it can happen.
    if (spillCandidate->workOffset == _currentOffset)
    {
      _compiler->setError(ERROR_REGISTERS_OVERLAP); <-- FAILS HERE
      return;
    }




Dňa utorok, 14. januára 2014 11:17:59 UTC+1 petr kobalicek napísal(-a):

Palo Marton

unread,
Jan 14, 2014, 7:43:18 AM1/14/14
to asmjit-dev
This is strange bug - because this seems to be caused by 2 bugs at once. One problem is here:

void CompilerContext::allocGPVar(VarData* vdata, uint32_t regMask, uint32_t vflags) ASMJIT_NOTHROW
...
  // If regMask contains restricted registers which may be used then everything
  // is handled in this block.
  if (regMask != Util::maskUpToIndex(REG_NUM_GP))
  {
    // Try to find unallocated register first.
    mask = regMask & ~_state.usedGP;
    if (mask != 0)
    {
      idx = Util::findFirstBit(
        (nonPreservedFirst && (mask & ~preservedGP) != 0) ? (mask & ~preservedGP) : mask);
      ASMJIT_ASSERT(idx != INVALID_VALUE);
    }
    // Then find the allocated and later spill.
    else
    {
      idx = Util::findFirstBit(regMask & _state.usedGP);
      ASMJIT_ASSERT(idx != INVALID_VALUE);

      // Spill register we need.
      spillCandidate = _state.gp[idx];
 ASMJIT_ASSERT(spillCandidate->workOffset != _currentOffset); <-- ADDED LINE

      // Jump to spill part of allocation.
      goto L_Spill;
    }
  }

This branch of code seems to miss check whether spilled variable is needed in the current instruction. I have patched that - it will scan for register where spillCandidate->workOffset != _currentOffset instead of using just Util::findFirstBit(regMask & _state.usedGP). Now my code works OK.

But there seems to be some other bug in play here: SETcc instruction has just one operand, so how it can happen that during allocation of this operand, there is some other variable marked as used by this instruction (workOffset==currentOffest)?

As this second bug is not causing any crashes, I will leave it as it is for now. But if you have some idea how this can happen, please let me know ;-)

Palo

Reply all
Reply to author
Forward
0 new messages