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; } }
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); } }
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 ); }
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); }
/* 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 ) ); }
/* 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 ); }
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); }
long PackedNavBits::asLong(const int startBit, const int numBits, const int scale) const { int64_t s = SignExtend( startBit, numBits); return( (long) (s * scale ) ); }
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 ) ) ) ) ); }
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; }
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--]; } }
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; }
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; }
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 ) ); }
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; }