예제 #1
0
파일: smlalxy.c 프로젝트: iamedu/armdev
void smlalxy_inst(ARMProc *proc, UWord instruction) {
        printf("Ejecutaste un smlalxy\n");
	UWord RdLo = get_bits(instruction,12,4);
        UWord RdHi = get_bits(instruction,16,4);
        Word Rs = get_bits(instruction,8,4);
        Word Rm = get_bits(instruction,0,4);
        Word x = get_bits(instruction,5,1);
        Word y = get_bits(instruction,6,1);
        Word last_rd;
	Word result;
	Word carry;
        Word operand1,operand2;
        if(cond(proc,instruction)){
                if(x == 0)
                        operand1 = SignExtend(get_bits(*proc->r[Rm],0,16),16);
                else
                        operand1 = SignExtend(get_bits(*proc->r[Rm],16,16),16);

                if(y == 0)
                        operand2 = SignExtend(get_bits(*proc->r[Rs],0,16),16);
                else
                        operand2 = SignExtend(get_bits(*proc->r[Rs],16,16),16);
		
		if((operand1 * operand2) < 0){
			result = 0xFFFFFFFF;
		}
		else{
			result = 0;
		}

		*proc->r[RdLo] = *proc->r[RdLo] + AddCarryFrom(RdLo,(operand1 * operand2),&carry);	
		*proc->r[RdHi] = *proc->r[RdHi] + *proc->r[RdLo] + result + carry;
        }

}
예제 #2
0
파일: smla.c 프로젝트: iamedu/armdev
void smla_inst(ARMProc *proc, UWord instruction) {
        printf("Ejecutaste un smla\n");
	Word Rm = get_bits(instruction,0,4);
        Word Rd = get_bits(instruction,16,4);
        Word Rs = get_bits(instruction,8,4);
        Word Rn = get_bits(instruction,12,4);
	Word x = get_bits(instruction,5,1);
	Word y = get_bits(instruction,6,1);
	Word last_rd;
	Word operand1,operand2;
        if(cond(proc,instruction)){
                if(x == 0)
               		operand1 = SignExtend(get_bits(*proc->r[Rm],0,16),16); 
		else
               		operand1 = SignExtend(get_bits(*proc->r[Rm],16,16),16);

		if(y == 0)
               		operand2 = SignExtend(get_bits(*proc->r[Rs],0,16),16); 
		else 
               		operand2 = SignExtend(get_bits(*proc->r[Rs],16,16),16); 
		last_rd = *proc->r[Rd];
		*proc->r[Rd] = (operand1 * operand2) + *proc->r[Rn];
		if(OverflowFrom(last_rd,*proc->r[Rn])) 
		        set_status(proc,status_q,1);
        }
}
예제 #3
0
   double PackedNavBits::asSignedDouble(const int startBit, const int numBits,  
                                        const int power2 ) const
   {
      int64_t s = SignExtend( startBit, numBits);

         // Convert to double and scale
      double dval = (double) s;
      dval *= pow(static_cast<double>(2), power2);
      return( dval );
   }
예제 #4
0
void CU_SignExtend()
{
	int r=0;
	Plgtab *imm = init_plgtab();
	Plage p = {0, 10, 2041};

	imm->plages = &p;
	imm->size = 1;


	CU_ASSERT((r = SignExtend(*imm)) == -6);

	printf("r = %i\n", r);

}
예제 #5
0
    /* Unpack a split signed long integer */
 long PackedNavBits::asLong(const unsigned startBits[],
                            const unsigned numBits[],
                            const unsigned len,
                            const int scale ) const
 {
    
    int64_t s = SignExtend(startBits[0], numBits[0]);
    uint64_t temp;
    for(unsigned int i = 1; i < len; i++){
       temp = asUint64_t(startBits[i], numBits[i]);
       s <<= numBits[i];
       s |= temp;
    }
    
    //int64_t s = SignExtend( startBit1, numBits1);
    //uint64_t temp2 = asUint64_t( startBit2, numBits2 );
    //s <<= numBits2;
    //s |= temp2;
    
    return( (long) (s * scale ) );
 }
예제 #6
0
      /* Unpack a split signed double */
   double PackedNavBits::asSignedDouble(const unsigned startBits[],
                                        const unsigned numBits[],
                                        const unsigned len,
                                        const int power2) const
   {
      int64_t s = SignExtend(startBits[0], numBits[0]);
      uint64_t temp;
      for(unsigned int i = 1; i < len; i++){
         temp = asUint64_t(startBits[i], numBits[i]);
         s <<= numBits[i];
         s |= temp;
      }
      
      //int64_t s = SignExtend( startBit1, numBits1);
      //uint64_t temp2 = asUint64_t( startBit2, numBits2 );
      //s <<= numBits2;
      //s |= temp2;

         // Convert to double and scale
      double dval = (double) s;
      dval *= pow(static_cast<double>(2), power2);
      return( dval );
   }
예제 #7
0
Expression* InterpreterEmulator::InterpreterExpressionVisitor::VisitOperation(u32 Type, Expression const* pLeftExpr, Expression const* pRightExpr)
{
  auto pLeft  = dynamic_cast<ContextExpression *>(pLeftExpr->Visit(this));
  auto pRight = dynamic_cast<ContextExpression *>(pRightExpr->Visit(this));

  if (pLeft == nullptr || pRight == nullptr)
  {
    delete pLeft;
    delete pRight;
    return nullptr;
  }

  u64 Left = 0, Right = 0;
  if (Type != OperationExpression::OpAff) /* OpAff doesn't require us to read left operand */
    if (pLeft ->Read(m_pCpuCtxt, m_pMemCtxt, m_pVarCtxt, Left) == false)
    {
      delete pLeft;
      delete pRight;
      return nullptr;
    }

  if (pRight->Read(m_pCpuCtxt, m_pMemCtxt, m_pVarCtxt, Right) == false)
  {
    delete pLeft;
    delete pRight;
    return nullptr;
  }

  Address LeftAddress, RightAddress;
  if (pLeft->GetAddress(m_pCpuCtxt, m_pMemCtxt, m_pVarCtxt, LeftAddress) == true)
  {
    auto itHook = m_rHooks.find(LeftAddress);
    if (itHook != std::end(m_rHooks) && itHook->second.m_Type & Emulator::HookOnWrite)
      itHook->second.m_Callback(m_pCpuCtxt, m_pMemCtxt);
  }

  if (pRight->GetAddress(m_pCpuCtxt, m_pMemCtxt, m_pVarCtxt, RightAddress) == true)
  {
    auto itHook = m_rHooks.find(RightAddress);
    if (itHook != std::end(m_rHooks) && itHook->second.m_Type & Emulator::HookOnRead)
      itHook->second.m_Callback(m_pCpuCtxt, m_pMemCtxt);
  }

  u64 SignedLeft = 0;
  pLeft->Read(m_pCpuCtxt, m_pMemCtxt, m_pVarCtxt, SignedLeft, true);

  switch (Type)
  {
  case OperationExpression::OpAdd:   Left +=  Right; break;
  case OperationExpression::OpSub:   Left -=  Right; break;
  case OperationExpression::OpMul:   Left = static_cast<s64>(SignedLeft) * Right; break;
  case OperationExpression::OpUDiv:
  case OperationExpression::OpSDiv:  Left /=  Right; break;
  case OperationExpression::OpAnd:   Left &=  Right; break;
  case OperationExpression::OpOr:    Left |=  Right; break;
  case OperationExpression::OpXor:   Left ^=  Right; break;
  case OperationExpression::OpLls:   Left <<= Right; break;
  case OperationExpression::OpLrs:   Left >>= Right; break;
  case OperationExpression::OpArs:   Left = static_cast<s64>(SignedLeft) >> Right; break;
  case OperationExpression::OpAff:   pLeft->Write(m_pCpuCtxt, m_pMemCtxt, m_pVarCtxt, Right); break;
  case OperationExpression::OpXchg:
    pLeft ->Write(m_pCpuCtxt, m_pMemCtxt, m_pVarCtxt, Right);
    pRight->Write(m_pCpuCtxt, m_pMemCtxt, m_pVarCtxt, Left );
    break;
  case OperationExpression::OpSext:
    {
      // FIXME: Handle error case
      u64 Value = 0;
      pLeft->Read(m_pCpuCtxt, m_pMemCtxt, m_pVarCtxt, Value, true);
      auto pReadValue = new ConstantExpression(static_cast<u32>(Right * 8), Value);
      pReadValue->SignExtend(pLeft->GetSizeInBit());
      delete pLeft;
      delete pRight;
      return pReadValue;
    }
  default: assert(0);
  }

  u32 Bit = pLeft->GetSizeInBit();
  delete pLeft;
  delete pRight;
  return new ConstantExpression(Bit, Left);
}
예제 #8
0
 long PackedNavBits::asLong(const int startBit, const int numBits,   
                            const int scale) const
 {
    int64_t s = SignExtend( startBit, numBits);
    return( (long) (s * scale ) );
 }
예제 #9
0
inline GPR_t si_andi( GPR_t RA, int16_t I10 )
{
	return _mm_castsi128_ps( _mm_and_si128( _mm_castps_si128( RA ), _mm_set1_epi32( static_cast<int32_t>(SignExtend( I10, 10 ) ) ) ) );
}
예제 #10
0
bool RARExecuteProgram(RARVirtualMachine *vm, RARProgram *prog)
{
    RAROpcode *opcode = prog->opcodes;
    uint32_t flags = 0;
    uint32_t op1, op2, carry, i;
    uint32_t counter = 0;

    if (!RARIsProgramTerminated(prog))
        return false;

    while ((uint32_t)(opcode - prog->opcodes) < prog->length && counter++ < RARRuntimeMaxInstructions) {
        switch (opcode->instruction) {
        case RARMovInstruction:
            SetOperand1(GetOperand2());
            NextInstruction();

        case RARCmpInstruction:
            op1 = GetOperand1();
            SetFlagsWithCarry(op1 - GetOperand2(), result > op1);
            NextInstruction();

        case RARAddInstruction:
            op1 = GetOperand1();
            if (opcode->bytemode)
                SetOperand1AndByteFlagsWithCarry((op1 + GetOperand2()) & 0xFF, result < op1);
            else
                SetOperand1AndFlagsWithCarry(op1 + GetOperand2(), result < op1);
            NextInstruction();

        case RARSubInstruction:
            op1 = GetOperand1();
#if 0 /* apparently not correctly implemented in the RAR VM */
            if (opcode->bytemode)
                SetOperand1AndByteFlagsWithCarry((op1 - GetOperand2()) & 0xFF, result > op1);
            else
#endif
            SetOperand1AndFlagsWithCarry(op1 - GetOperand2(), result > op1);
            NextInstruction();

        case RARJzInstruction:
            if ((flags & ZeroFlag))
                Jump(GetOperand1());
            NextInstruction();

        case RARJnzInstruction:
            if (!(flags & ZeroFlag))
                Jump(GetOperand1());
            NextInstruction();

        case RARIncInstruction:
            if (opcode->bytemode)
                SetOperand1AndFlags((GetOperand1() + 1) & 0xFF);
            else
                SetOperand1AndFlags(GetOperand1() + 1);
            NextInstruction();

        case RARDecInstruction:
            if (opcode->bytemode)
                SetOperand1AndFlags((GetOperand1() - 1) & 0xFF);
            else
                SetOperand1AndFlags(GetOperand1() - 1);
            NextInstruction();

        case RARJmpInstruction:
            Jump(GetOperand1());

        case RARXorInstruction:
            SetOperand1AndFlags(GetOperand1() ^ GetOperand2());
            NextInstruction();

        case RARAndInstruction:
            SetOperand1AndFlags(GetOperand1() & GetOperand2());
            NextInstruction();

        case RAROrInstruction:
            SetOperand1AndFlags(GetOperand1() | GetOperand2());
            NextInstruction();

        case RARTestInstruction:
            SetFlags(GetOperand1() & GetOperand2());
            NextInstruction();

        case RARJsInstruction:
            if ((flags & SignFlag))
                Jump(GetOperand1());
            NextInstruction();

        case RARJnsInstruction:
            if (!(flags & SignFlag))
                Jump(GetOperand1());
            NextInstruction();

        case RARJbInstruction:
            if ((flags & CarryFlag))
                Jump(GetOperand1());
            NextInstruction();

        case RARJbeInstruction:
            if ((flags & (CarryFlag | ZeroFlag)))
                Jump(GetOperand1());
            NextInstruction();

        case RARJaInstruction:
            if (!(flags & (CarryFlag | ZeroFlag)))
                Jump(GetOperand1());
            NextInstruction();

        case RARJaeInstruction:
            if (!(flags & CarryFlag))
                Jump(GetOperand1());
            NextInstruction();

        case RARPushInstruction:
            vm->registers[7] -= 4;
            RARVirtualMachineWrite32(vm, vm->registers[7], GetOperand1());
            NextInstruction();

        case RARPopInstruction:
            SetOperand1(RARVirtualMachineRead32(vm, vm->registers[7]));
            vm->registers[7] += 4;
            NextInstruction();

        case RARCallInstruction:
            vm->registers[7] -= 4;
            RARVirtualMachineWrite32(vm, vm->registers[7], (uint32_t)(opcode - prog->opcodes + 1));
            Jump(GetOperand1());

        case RARRetInstruction:
            if (vm->registers[7] >= RARProgramMemorySize)
                return true;
            i = RARVirtualMachineRead32(vm, vm->registers[7]);
            vm->registers[7] += 4;
            Jump(i);

        case RARNotInstruction:
            SetOperand1(~GetOperand1());
            NextInstruction();

        case RARShlInstruction:
            op1 = GetOperand1();
            op2 = GetOperand2();
            SetOperand1AndFlagsWithCarry(op1 << op2, ((op1 << (op2 - 1)) & 0x80000000) != 0);
            NextInstruction();

        case RARShrInstruction:
            op1 = GetOperand1();
            op2 = GetOperand2();
            SetOperand1AndFlagsWithCarry(op1 >> op2, ((op1 >> (op2 - 1)) & 1) != 0);
            NextInstruction();

        case RARSarInstruction:
            op1 = GetOperand1();
            op2 = GetOperand2();
            SetOperand1AndFlagsWithCarry(((int32_t)op1) >> op2, ((op1 >> (op2 - 1)) & 1) != 0);
            NextInstruction();

        case RARNegInstruction:
            SetOperand1AndFlagsWithCarry(-(int32_t)GetOperand1(), result != 0);
            NextInstruction();

        case RARPushaInstruction:
            vm->registers[7] -= 32;
            for (i = 0; i < 8; i++)
                RARVirtualMachineWrite32(vm, vm->registers[7] + (7 - i) * 4, vm->registers[i]);
            NextInstruction();

        case RARPopaInstruction:
            for (i = 0; i < 8; i++)
                vm->registers[i] = RARVirtualMachineRead32(vm, vm->registers[7] + (7 - i) * 4);
            vm->registers[7] += 32;
            NextInstruction();

        case RARPushfInstruction:
            vm->registers[7] -= 4;
            RARVirtualMachineWrite32(vm, vm->registers[7], flags);
            NextInstruction();

        case RARPopfInstruction:
            flags = RARVirtualMachineRead32(vm, vm->registers[7]);
            vm->registers[7] += 4;
            NextInstruction();

        case RARMovzxInstruction:
            SetOperand1(GetOperand2());
            NextInstruction();

        case RARMovsxInstruction:
            SetOperand1(SignExtend(GetOperand2()));
            NextInstruction();

        case RARXchgInstruction:
            op1 = GetOperand1();
            op2 = GetOperand2();
            SetOperand1(op2);
            SetOperand2(op1);
            NextInstruction();

        case RARMulInstruction:
            SetOperand1(GetOperand1() * GetOperand2());
            NextInstruction();

        case RARDivInstruction:
            op2 = GetOperand2();
            if (op2 != 0)
                SetOperand1(GetOperand1() / op2);
            NextInstruction();

        case RARAdcInstruction:
            op1 = GetOperand1();
            carry = (flags & CarryFlag);
            if (opcode->bytemode)
                SetOperand1AndFlagsWithCarry((op1 + GetOperand2() + carry) & 0xFF, result < op1 || (result == op1 && carry)); /* does not correctly set sign bit */
            else
                SetOperand1AndFlagsWithCarry(op1 + GetOperand2() + carry, result < op1 || (result == op1 && carry));
            NextInstruction();

        case RARSbbInstruction:
            op1 = GetOperand1();
            carry = (flags & CarryFlag);
            if (opcode->bytemode)
                SetOperand1AndFlagsWithCarry((op1 - GetOperand2() - carry) & 0xFF, result > op1 || (result == op1 && carry)); /* does not correctly set sign bit */
            else
                SetOperand1AndFlagsWithCarry(op1 - GetOperand2() - carry, result > op1 || (result == op1 && carry));
            NextInstruction();

        case RARPrintInstruction:
            /* TODO: ??? */
            NextInstruction();
        }
    }

    return false;
}
예제 #11
0
le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success)
{
    const LigatureSubstitutionStateEntry2 *entry = entryTable.getAlias(index, success);
    if(LE_FAILURE(success)) return 0;

    le_uint16 nextStateIndex = SWAPW(entry->nextStateIndex);
    le_uint16 flags = SWAPW(entry->entryFlags);
    le_uint16 ligActionIndex = SWAPW(entry->ligActionIndex);

    if (flags & lsfSetComponent) {
        if (++m >= nComponents) {
            m = 0;
        }
        componentStack[m] = currGlyph;
    } else if ( m == -1) {
        // bad font- skip this glyph.
        //LE_DEBUG_BAD_FONT("m==-1 (componentCount went negative)")
        currGlyph+= dir;
        return nextStateIndex;
    }

    ByteOffset actionOffset = flags & lsfPerformAction;

    if (actionOffset != 0) {
        LEReferenceTo<LigatureActionEntry> ap(stHeader, success, ligActionOffset); // byte offset
        if (LE_FAILURE(success)) {
            currGlyph+= dir;
            return nextStateIndex;
        }
        ap.addObject(ligActionIndex, success);
        LEReferenceToArrayOf<TTGlyphID> ligatureTable(stHeader, success, ligatureOffset, LE_UNBOUNDED_ARRAY);
        LigatureActionEntry action;
        le_int32 offset, i = 0, j = 0;
        le_int32 stack[nComponents];
        le_int16 mm = -1;

        LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY);
        if(LE_FAILURE(success)) {
            currGlyph+= dir;
            return nextStateIndex; // get out! bad font
        }

        do {
            le_uint32 componentGlyph = componentStack[m--]; // pop off

            if (j++ > 0) {
                ap.addObject(success);
            }
            if (LE_FAILURE(success)) {
                currGlyph+= dir;
                return nextStateIndex;
            }

            action = SWAPL(*ap.getAlias());

            if (m < 0) {
                m = nComponents - 1;
            }

            offset = action & lafComponentOffsetMask;
            if (offset != 0) {
                if(componentGlyph >= glyphStorage.getGlyphCount()) {
                  LE_DEBUG_BAD_FONT("preposterous componentGlyph");
                  currGlyph+= dir;
                  return nextStateIndex; // get out! bad font
                }
                i += SWAPW(componentTable(LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask)),success));
                if (LE_FAILURE(success)) {
                    currGlyph+= dir;
                    return nextStateIndex;
                }

                if (action & (lafLast | lafStore))  {
                  TTGlyphID ligatureGlyph = SWAPW(ligatureTable(i,success));
                  if (LE_FAILURE(success)) {
                      currGlyph+= dir;
                      return nextStateIndex;
                  }
                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
                    if(mm==nComponents) {
                      LE_DEBUG_BAD_FONT("exceeded nComponents");
                      mm--; // don't overrun the stack.
                    }
                    stack[++mm] = componentGlyph;
                    i = 0;
                } else {
                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
                }
            }
#if LE_ASSERT_BAD_FONT
            if(m<0) {
              LE_DEBUG_BAD_FONT("m<0")
            }
#endif
        } while (LE_SUCCESS(success) && !(action & lafLast) && (m>=0) ); // stop if last bit is set, or if run out of items

        while (mm >= 0) {
            if (++m >= nComponents) {
                m = 0;
            }

            componentStack[m] = stack[mm--];
        }
    }
예제 #12
0
static bool RunVirtualMachineOrGetLabels(RARVirtualMachine *self,
RAROpcode *opcodes,int numopcodes,void ***instructionlabels)
{
	static void *labels[2][RARNumberOfInstructions]=
	{
		[0][RARMovInstruction]=&&MovLabel,[1][RARMovInstruction]=&&MovLabel,
		[0][RARCmpInstruction]=&&CmpLabel,[1][RARCmpInstruction]=&&CmpLabel,
		[0][RARAddInstruction]=&&AddLabel,[1][RARAddInstruction]=&&AddByteLabel,
		[0][RARSubInstruction]=&&SubLabel,[1][RARSubInstruction]=&&SubLabel,
		[0][RARJzInstruction]=&&JzLabel,
		[0][RARJnzInstruction]=&&JnzLabel,
		[0][RARIncInstruction]=&&IncLabel,[1][RARIncInstruction]=&&IncByteLabel,
		[0][RARDecInstruction]=&&DecLabel,[1][RARDecInstruction]=&&DecByteLabel,
		[0][RARJmpInstruction]=&&JmpLabel,
		[0][RARXorInstruction]=&&XorLabel,[1][RARXorInstruction]=&&XorLabel,
		[0][RARAndInstruction]=&&AndLabel,[1][RARAndInstruction]=&&AndLabel,
		[0][RAROrInstruction]=&&OrLabel,[1][RAROrInstruction]=&&OrLabel,
		[0][RARTestInstruction]=&&TestLabel,[1][RARTestInstruction]=&&TestLabel,
		[0][RARJsInstruction]=&&JsLabel,
		[0][RARJnsInstruction]=&&JnsLabel,
		[0][RARJbInstruction]=&&JbLabel,
		[0][RARJbeInstruction]=&&JbeLabel,
		[0][RARJaInstruction]=&&JaLabel,
		[0][RARJaeInstruction]=&&JaeLabel,
		[0][RARPushInstruction]=&&PushLabel,
		[0][RARPopInstruction]=&&PopLabel,
		[0][RARCallInstruction]=&&CallLabel,
		[0][RARRetInstruction]=&&RetLabel,
		[0][RARNotInstruction]=&&NotLabel,[1][RARNotInstruction]=&&NotLabel,
		[0][RARShlInstruction]=&&ShlLabel,[1][RARShlInstruction]=&&ShlLabel,
		[0][RARShrInstruction]=&&ShrLabel,[1][RARShrInstruction]=&&ShrLabel,
		[0][RARSarInstruction]=&&SarLabel,[1][RARSarInstruction]=&&SarLabel,
		[0][RARNegInstruction]=&&NegLabel,[1][RARNegInstruction]=&&NegLabel,
		[0][RARPushaInstruction]=&&PushaLabel,
		[0][RARPopaInstruction]=&&PopaLabel,
		[0][RARPushfInstruction]=&&PushfLabel,
		[0][RARPopfInstruction]=&&PopfLabel,
		[0][RARMovzxInstruction]=&&MovzxLabel,
		[0][RARMovsxInstruction]=&&MovsxLabel,
		[0][RARXchgInstruction]=&&XchgLabel,
		[0][RARMulInstruction]=&&MulLabel,[1][RARMulInstruction]=&&MulLabel,
		[0][RARDivInstruction]=&&DivLabel,[1][RARDivInstruction]=&&DivLabel,
		[0][RARAdcInstruction]=&&AdcLabel,[1][RARAdcInstruction]=&&AdcByteLabel,
		[0][RARSbbInstruction]=&&SbbLabel,[1][RARSbbInstruction]=&&SbbByteLabel,
		[0][RARPrintInstruction]=&&PrintLabel,
	};

	if(instructionlabels)
	{
		*instructionlabels=&labels[0][0];
		return true;
	}

	RAROpcode *opcode;
	uint32_t flags=self->flags;

	Jump(0);

	MovLabel:
		SetOperand1(GetOperand2());
		NextInstruction();

	CmpLabel:
	{
		uint32_t term1=GetOperand1();
		SetFlagsWithCarry(term1-GetOperand2(),result>term1);
		NextInstruction();
	}

	AddLabel:
	{
		uint32_t term1=GetOperand1();
		SetOperand1AndFlagsWithCarry(term1+GetOperand2(),result<term1);
		NextInstruction();
	}
	AddByteLabel:
	{
		uint32_t term1=GetOperand1();
		SetOperand1AndByteFlagsWithCarry(term1+GetOperand2()&0xff,result<term1);
		NextInstruction();
	}

	SubLabel:
	{
		uint32_t term1=GetOperand1();
		SetOperand1AndFlagsWithCarry(term1-GetOperand2(),result>term1);
		NextInstruction();
	}
/*	SubByteLabel: // Not correctly implemented in the RAR VM
	{
		uint32_t term1=GetOperand1();
		SetOperandAndByteFlagsWithCarry(term1-GetOperand2()&0xff,result>term1);
		NextInstruction();
	}*/

	JzLabel:
		if(flags&ZeroFlag) Jump(GetOperand1());
		else NextInstruction();

	JnzLabel:
		if(!(flags&ZeroFlag)) Jump(GetOperand1());
		else NextInstruction();

	IncLabel:
		SetOperand1AndFlags(GetOperand1()+1);
		NextInstruction();
	IncByteLabel:
		SetOperand1AndFlags(GetOperand1()+1&0xff);
		NextInstruction();

	DecLabel:
		SetOperand1AndFlags(GetOperand1()-1);
		NextInstruction();
	DecByteLabel:
		SetOperand1AndFlags(GetOperand1()-1&0xff);
		NextInstruction();

	JmpLabel:
		Jump(GetOperand1());

	XorLabel:
		SetOperand1AndFlags(GetOperand1()^GetOperand2());
		NextInstruction();

	AndLabel:
		SetOperand1AndFlags(GetOperand1()&GetOperand2());
		NextInstruction();

	OrLabel:
		SetOperand1AndFlags(GetOperand1()|GetOperand2());
		NextInstruction();

	TestLabel:
		SetFlags(GetOperand1()&GetOperand2());
		NextInstruction();

	JsLabel:
		if(flags&SignFlag) Jump(GetOperand1());
		else NextInstruction();

	JnsLabel:
		if(!(flags&SignFlag)) Jump(GetOperand1());
		else NextInstruction();

	JbLabel:
		if(flags&CarryFlag) Jump(GetOperand1());
		else NextInstruction();

	JbeLabel:
		if(flags&(CarryFlag|ZeroFlag)) Jump(GetOperand1());
		else NextInstruction();

	JaLabel:
		if(!(flags&(CarryFlag|ZeroFlag))) Jump(GetOperand1());
		else NextInstruction();

	JaeLabel:
		if(!(flags&CarryFlag)) Jump(GetOperand1());
		else NextInstruction();

	PushLabel:
		self->registers[7]-=4;
		RARVirtualMachineWrite32(self,self->registers[7],GetOperand1());
		NextInstruction();

	PopLabel:
		SetOperand1(RARVirtualMachineRead32(self,self->registers[7]));
		self->registers[7]+=4;
		NextInstruction();

	CallLabel:
		self->registers[7]-=4;
		RARVirtualMachineWrite32(self,self->registers[7],opcode-opcodes+1);
		Jump(GetOperand1());

	RetLabel:
	{
		if(self->registers[7]>=RARProgramMemorySize)
		{
			self->flags=flags;
			return true;
		}
		uint32_t retaddr=RARVirtualMachineRead32(self,self->registers[7]);
		self->registers[7]+=4;
		Jump(retaddr);
	}

	NotLabel:
		SetOperand1(~GetOperand1());
		NextInstruction();

	ShlLabel:
	{
		uint32_t op1=GetOperand1();
		uint32_t op2=GetOperand2();
		SetOperand1AndFlagsWithCarry(op1<<op2,((op1<<(op2-1))&0x80000000)!=0);
		NextInstruction();
	}

	ShrLabel:
	{
		uint32_t op1=GetOperand1();
		uint32_t op2=GetOperand2();
		SetOperand1AndFlagsWithCarry(op1>>op2,((op1>>(op2-1))&1)!=0);
		NextInstruction();
	}

	SarLabel:
	{
		uint32_t op1=GetOperand1();
		uint32_t op2=GetOperand2();
		SetOperand1AndFlagsWithCarry(((int32_t)op1)>>op2,((op1>>(op2-1))&1)!=0);
		NextInstruction();
	}

	NegLabel:
		SetOperand1AndFlagsWithCarry(-GetOperand1(),result!=0);
		NextInstruction();

	PushaLabel:
		for(int i=0;i<8;i++) RARVirtualMachineWrite32(self,self->registers[7]-4-i*4,self->registers[i]);
		self->registers[7]-=32;

		NextInstruction();

	PopaLabel:
		for(int i=0;i<8;i++) self->registers[i]=RARVirtualMachineRead32(self,self->registers[7]+28-i*4);
		NextInstruction();

	PushfLabel:
		self->registers[7]-=4;
		RARVirtualMachineWrite32(self,self->registers[7],flags);
		NextInstruction();

	PopfLabel:
		flags=RARVirtualMachineRead32(self,self->registers[7]);
		self->registers[7]+=4;
		NextInstruction();

	MovzxLabel:
		SetOperand1(GetOperand2());
		NextInstruction();

	MovsxLabel:
		SetOperand1(SignExtend(GetOperand2()));
		NextInstruction();

	XchgLabel:
	{
		uint32_t op1=GetOperand1();
		uint32_t op2=GetOperand2();
		SetOperand1(op2);
		SetOperand2(op1);
		NextInstruction();
	}

	MulLabel:
		SetOperand1(GetOperand1()*GetOperand2());
		NextInstruction();

	DivLabel:
	{
		uint32_t denominator=GetOperand2();
		if(denominator!=0) SetOperand1(GetOperand1()/denominator);
		NextInstruction();
	}

	AdcLabel:
	{
		uint32_t term1=GetOperand1();
		uint32_t carry=flags&CarryFlag;
		SetOperand1AndFlagsWithCarry(term1+GetOperand2()+carry,result<term1 || result==term1 && carry);
		NextInstruction();
	}
	AdcByteLabel:
	{
		uint32_t term1=GetOperand1();
		uint32_t carry=flags&CarryFlag;
		SetOperand1AndFlagsWithCarry(term1+GetOperand2()+carry&0xff,result<term1 || result==term1 && carry); // Does not correctly set sign bit.
		NextInstruction();
	}

	SbbLabel:
	{
		uint32_t term1=GetOperand1();
		uint32_t carry=flags&CarryFlag;
		SetOperand1AndFlagsWithCarry(term1-GetOperand2()-carry,result>term1 || result==term1 && carry);
		NextInstruction();
	}
	SbbByteLabel:
	{
		uint32_t term1=GetOperand1();
		uint32_t carry=flags&CarryFlag;
		SetOperand1AndFlagsWithCarry(term1-GetOperand2()-carry&0xff,result>term1 || result==term1 && carry); // Does not correctly set sign bit.
		NextInstruction();
	}

	PrintLabel:
		NextInstruction();

	return false;
}
예제 #13
0
le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
{
    const LigatureSubstitutionStateEntry2 *entry = &entryTable[index];
    le_uint16 nextStateIndex = SWAPW(entry->nextStateIndex);
    le_uint16 flags = SWAPW(entry->entryFlags);
    le_uint16 ligActionIndex = SWAPW(entry->ligActionIndex);
    
    if (flags & lsfSetComponent) {
        if (++m >= nComponents) {
            m = 0;
        }
        componentStack[m] = currGlyph;
    }

    ByteOffset actionOffset = flags & lsfPerformAction;

    if (actionOffset != 0) {
        const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + ligActionOffset) + ligActionIndex;
        const TTGlyphID *ligatureTable = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + ligatureOffset);
        LigatureActionEntry action;
        le_int32 offset, i = 0;
        le_int32 stack[nComponents];
        le_int16 mm = -1;

        const le_uint16 *componentTable = (const le_uint16 *)((char *) &ligatureSubstitutionHeader->stHeader + componentOffset);
        
        do {
            le_uint32 componentGlyph = componentStack[m--]; // pop off

            action = SWAPL(*ap++);

            if (m < 0) {
                m = nComponents - 1;
            }

            offset = action & lafComponentOffsetMask;
            if (offset != 0) {
                
                i += SWAPW(componentTable[LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask))]);
                       
                if (action & (lafLast | lafStore))  {
                    TTGlyphID ligatureGlyph = SWAPW(ligatureTable[i]);
                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
                    stack[++mm] = componentGlyph;
                    i = 0;
                } else {
                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
                }
            }
        } while (!(action & lafLast));

        while (mm >= 0) {
            if (++m >= nComponents) {
                m = 0;
            }

            componentStack[m] = stack[mm--];
        }
    }

    if (!(flags & lsfDontAdvance)) {
        currGlyph += dir;
    }

    return nextStateIndex;
}
예제 #14
0
void spu_rotmahi( SPU_t* SPU, SPU_INSTRUCTION op )
{
	const int s = 0x1f&( 0 - SignExtend(op.RI7.I7, 7) );
	SPU->GPR[op.RI7.RT] = _mm_castsi128_ps( _mm_srai_epi16( _mm_castps_si128( SPU->GPR[op.RI7.RA] ), s ) );
}
예제 #15
0
파일: spu_idb.cpp 프로젝트: grumpos/spuc
SPU_OP_COMPONENTS spu_decode_op_components( uint32_t raw_instr )
{
	const SPU_INSTRUCTION op = (SPU_INSTRUCTION&)raw_instr;
	const SPU_OP_TYPE itype = spu_decode_op_type(raw_instr);

	switch (itype)
	{
	case SPU_OP_TYPE_RRR:
		{
			const SPU_OP_COMPONENTS result = { op.RRR.RT,	op.RRR.RA,	op.RRR.RB,	op.RRR.RC,	0 };
			return result;
		}
	case SPU_OP_TYPE_RR:
		{
			const SPU_OP_COMPONENTS result = { op.RR.RT,	op.RR.RA,	op.RR.RB,	0,			0 };
			return result;
		}
	case SPU_OP_TYPE_RI7:
		{
			const SPU_OP_COMPONENTS result = { op.RI7.RT,	op.RI7.RA,	0,			0,			SignExtend(op.RI7.I7, 7) };
			return result;
		}
	case SPU_OP_TYPE_RI8:
		{
			const SPU_OP_COMPONENTS result = { op.RI8.RT,	op.RI8.RA,	0,			0,			SignExtend(op.RI8.I8, 8) };
			return result;
		}
	case SPU_OP_TYPE_RI10:
		{
			const SPU_OP_COMPONENTS result = { op.RI10.RT,	op.RI10.RA,	0,			0,			SignExtend(op.RI10.I10, 10) };
			return result;
		}
	case SPU_OP_TYPE_RI16:
		{
			const SPU_OP_COMPONENTS result = { op.RI16.RT,	0,			0,			0,			SignExtend(op.RI16.I16, 16) };
			return result;
		}
	case SPU_OP_TYPE_RI18:
		{
			const SPU_OP_COMPONENTS result = { op.RI18.RT,	0,			0,			0,			SignExtend(op.RI18.I18, 18) };
			return result;
		}
	case SPU_OP_TYPE_LBT:
		{
			const uint32_t BRTARG = (uint32_t)SignExtend( op.LBT.I16, 16 );
			const uint32_t BRINST = (uint32_t)SignExtend( ((uint32_t)op.LBT.ROH << 7) | (uint32_t)op.LBT.ROL, 11 );
			const SPU_OP_COMPONENTS result = { 0, 0, 0, 0, (int64_t)(((uint64_t)BRTARG << 32) | (uint64_t)BRINST) };
			return result;
		}
	case SPU_OP_TYPE_LBTI:
		{
			const uint32_t BRTARG = (uint32_t)SignExtend( ((uint32_t)op.LBTI.ROH << 7) | (uint32_t)op.LBTI.ROL, 11 );
			const uint32_t BRINST = 0;
			const SPU_OP_COMPONENTS result = { 0, op.LBTI.RA, 0, 0, (int64_t)(((uint64_t)BRTARG << 32) | (uint64_t)BRINST) };
			return result;
		}
	default:
		{
			const SPU_OP_COMPONENTS result = { 0 };
			return result;
		}
	}
}
ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
{
  LEErrorCode success = LE_NO_ERROR;
  const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);

    ByteOffset newState = SWAPW(entry->newStateOffset);
    le_int16 flags = SWAPW(entry->flags);

    if (flags & lsfSetComponent) {
        if (++m >= nComponents) {
            m = 0;
        }

        componentStack[m] = currGlyph;
    } else if ( m == -1) {
        // bad font- skip this glyph.
        currGlyph++;
        return newState;
    }

    ByteOffset actionOffset = flags & lsfActionOffsetMask;

    if (actionOffset != 0) {
      LEReferenceTo<LigatureActionEntry> ap(stHeader, success, actionOffset);
        LigatureActionEntry action;
        le_int32 offset, i = 0;
        le_int32 stack[nComponents];
        le_int16 mm = -1;

        do {
            le_uint32 componentGlyph = componentStack[m--];

            action = SWAPL(*ap.getAlias());
            ap.addObject(success); // ap++

            if (m < 0) {
                m = nComponents - 1;
            }

            offset = action & lafComponentOffsetMask;
            if (offset != 0) {
              LEReferenceToArrayOf<le_int16> offsetTable(stHeader, success, 2 * SignExtend(offset, lafComponentOffsetMask), LE_UNBOUNDED_ARRAY);

              if(LE_FAILURE(success)) {
                  currGlyph++;
                  LE_DEBUG_BAD_FONT("off end of ligature substitution header");
                  return newState; // get out! bad font
              }
              if(componentGlyph > glyphStorage.getGlyphCount()) {
                LE_DEBUG_BAD_FONT("preposterous componentGlyph");
                currGlyph++;
                return newState; // get out! bad font
              }
              i += SWAPW(offsetTable.getObject(LE_GET_GLYPH(glyphStorage[componentGlyph]), success));

                if (action & (lafLast | lafStore))  {
                  LEReferenceTo<TTGlyphID> ligatureOffset(stHeader, success, i);
                  TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset.getAlias());

                  glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
                  if(mm==nComponents) {
                    LE_DEBUG_BAD_FONT("exceeded nComponents");
                    mm--; // don't overrun the stack.
                  }
                  stack[++mm] = componentGlyph;
                  i = 0;
                } else {
                  glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
                }
            }
#if LE_ASSERT_BAD_FONT
            if(m<0) {
              LE_DEBUG_BAD_FONT("m<0")
            }
#endif
        } while (!(action & lafLast)  && (m>=0) ); // stop if last bit is set, or if run out of items

        while (mm >= 0) {
          if (++m >= nComponents) {
            m = 0;
          }

          componentStack[m] = stack[mm--];
        }
    }
ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
{
    const LigatureSubstitutionStateEntry *entry = &entryTable[index];
    ByteOffset newState = SWAPW(entry->newStateOffset);
    le_int16 flags = SWAPW(entry->flags);

    if (flags & lsfSetComponent) {
        if (++m >= nComponents) {
            m = 0;
        }

        componentStack[m] = currGlyph;
    }

    ByteOffset actionOffset = flags & lsfActionOffsetMask;

    if (actionOffset != 0) {
        const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + actionOffset);
        LigatureActionEntry action;
        le_int32 offset, i = 0;
        le_int32 stack[nComponents];
        le_int16 mm = -1;

        do {
            le_uint32 componentGlyph = componentStack[m--];

            action = SWAPL(*ap++);

            if (m < 0) {
                m = nComponents - 1;
            }

            offset = action & lafComponentOffsetMask;
            if (offset != 0) {
                const le_int16 *offsetTable = (const le_int16 *)((char *) &ligatureSubstitutionHeader->stHeader + 2 * SignExtend(offset, lafComponentOffsetMask));

                i += SWAPW(offsetTable[LE_GET_GLYPH(glyphStorage[componentGlyph])]);

                if (action & (lafLast | lafStore))  {
                    const TTGlyphID *ligatureOffset = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + i);
                    TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset);

                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
                    stack[++mm] = componentGlyph;
                    i = 0;
                } else {
                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
                }
            }
        } while (!(action & lafLast));

        while (mm >= 0) {
            if (++m >= nComponents) {
                m = 0;
            }

            componentStack[m] = stack[mm--];
        }
    }

    if (!(flags & lsfDontAdvance)) {
        // should handle reverse too!
        currGlyph += 1;
    }

    return newState;
}