예제 #1
0
/* virtual */ void CHCICommandBase::Match(const THCIEventBase& aEvent, TBool& aMatchesCmd, TBool& aConcludesCmd, TBool& aContinueMatching) const
	{
	THCIEventCode eventCode(aEvent.EventCode());

	if (eventCode == ECommandCompleteEvent)
		{
		THCICommandCompleteEvent& event = THCICommandCompleteEvent::Cast(aEvent);
		aMatchesCmd			= (event.CommandOpcode() == Opcode());
		aConcludesCmd		= aMatchesCmd;
		aContinueMatching	= !aMatchesCmd;
		}
	else if (eventCode == ECommandStatusEvent)
		{
		TCommandStatusEvent& event = TCommandStatusEvent::Cast(aEvent);
		aMatchesCmd			= (event.CommandOpcode() == Opcode());
		// If the status is an error then this event concludes the command
		aConcludesCmd		= (aMatchesCmd && (event.ErrorCode() != EOK));
		aContinueMatching	= !aMatchesCmd;
		}
	else
		{
		aMatchesCmd			= EFalse;
		aConcludesCmd		= EFalse;
		aContinueMatching	= EFalse;
		}
	}
예제 #2
0
//=============================================================================
//------------------------------Identity---------------------------------------
// If right input is a constant 0, return the left input.  
Node *SubNode::Identity( PhaseTransform *phase ) {
  assert(in(1) != this, "Must already have called Value");
  assert(in(2) != this, "Must already have called Value");

  // Remove double negation
  const Type *zero = add_id();
  if( phase->type( in(1) )->higher_equal( zero ) &&
      in(2)->Opcode() == Opcode() &&
      phase->type( in(2)->in(1) )->higher_equal( zero ) ) {
    return in(2)->in(2);
  }

  // Convert "(X+Y) - Y" into X
  if( in(1)->Opcode() == Op_AddI ) {
    if( phase->eqv(in(1)->in(2),in(2)) )
      return in(1)->in(1);
    // Also catch: "(X + Opaque2(Y)) - Y".  In this case, 'Y' is a loop-varying
    // trip counter and X is likely to be loop-invariant (that's how O2 Nodes
    // are originally used, although the optimizer sometimes jiggers things).
    // This folding through an O2 removes a loop-exit use of a loop-varying
    // value and generally lowers register pressure in and around the loop.
    if( in(1)->in(2)->Opcode() == Op_Opaque2 &&
        phase->eqv(in(1)->in(2)->in(1),in(2)) )
      return in(1)->in(1);
  }

  return ( phase->type( in(2) )->higher_equal( zero ) ) ? in(1) : this;
}
예제 #3
0
//------------------------------proj_out---------------------------------------
// Get a named projection
ProjNode* MultiNode::proj_out(uint which_proj) const {
  assert(Opcode() != Op_If || which_proj == (uint)true || which_proj == (uint)false, "must be 1 or 0");
  assert(Opcode() != Op_If || outcnt() == 2, "bad if #1");
  for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) {
    Node *p = fast_out(i);
    if( !p->is_Proj() ) {
      assert(p == this && this->is_Start(), "else must be proj");
      continue;
    }
    ProjNode *proj = p->as_Proj();
    if( proj->_con == which_proj ) {
      assert(Opcode() != Op_If || proj->Opcode() == (which_proj?Op_IfTrue:Op_IfFalse), "bad if #2");
      return proj;
    }
  }
  return NULL;
}
예제 #4
0
파일: MemMap.cpp 프로젝트: Orphis/ppsspp
Opcode Read_Opcode_JIT(u32 address)
{
	Opcode inst = Opcode(Read_U32(address));
	if (MIPS_IS_RUNBLOCK(inst.encoding) && MIPSComp::jit) {
		return MIPSComp::jit->GetOriginalOp(inst);
	} else {
		return inst;
	}
}
예제 #5
0
파일: MemMap.cpp 프로젝트: ANR2ME/ppsspp
static Opcode Read_Instruction(u32 address, bool resolveReplacements, Opcode inst)
{
	if (!MIPS_IS_EMUHACK(inst.encoding)) {
		return inst;
	}

	if (MIPS_IS_RUNBLOCK(inst.encoding) && MIPSComp::jit) {
		JitBlockCache *bc = MIPSComp::jit->GetBlockCache();
		int block_num = bc->GetBlockNumberFromEmuHackOp(inst, true);
		if (block_num >= 0) {
			inst = bc->GetOriginalFirstOp(block_num);
			if (resolveReplacements && MIPS_IS_REPLACEMENT(inst)) {
				u32 op;
				if (GetReplacedOpAt(address, &op)) {
					if (MIPS_IS_EMUHACK(op)) {
						ERROR_LOG(HLE,"WTF 1");
						return Opcode(op);
					} else {
						return Opcode(op);
					}
				} else {
					ERROR_LOG(HLE, "Replacement, but no replacement op? %08x", inst.encoding);
				}
			}
			return inst;
		} else {
			return inst;
		}
	} else if (resolveReplacements && MIPS_IS_REPLACEMENT(inst.encoding)) {
		u32 op;
		if (GetReplacedOpAt(address, &op)) {
			if (MIPS_IS_EMUHACK(op)) {
				ERROR_LOG(HLE,"WTF 2");
				return Opcode(op);
			} else {
				return Opcode(op);
			}
		} else {
			return inst;
		}
	} else {
		return inst;
	}
}
예제 #6
0
파일: MemMap.cpp 프로젝트: Orphis/ppsspp
__forceinline static Opcode Read_Instruction(u32 address, bool resolveReplacements, Opcode inst)
{
	if (!MIPS_IS_EMUHACK(inst.encoding)) {
		return inst;
	}

	if (MIPS_IS_RUNBLOCK(inst.encoding) && MIPSComp::jit) {
		inst = MIPSComp::jit->GetOriginalOp(inst);
		if (resolveReplacements && MIPS_IS_REPLACEMENT(inst)) {
			u32 op;
			if (GetReplacedOpAt(address, &op)) {
				if (MIPS_IS_EMUHACK(op)) {
					ERROR_LOG(MEMMAP, "WTF 1");
					return Opcode(op);
				} else {
					return Opcode(op);
				}
			} else {
				ERROR_LOG(MEMMAP, "Replacement, but no replacement op? %08x", inst.encoding);
			}
		}
		return inst;
	} else if (resolveReplacements && MIPS_IS_REPLACEMENT(inst.encoding)) {
		u32 op;
		if (GetReplacedOpAt(address, &op)) {
			if (MIPS_IS_EMUHACK(op)) {
				ERROR_LOG(MEMMAP, "WTF 2");
				return Opcode(op);
			} else {
				return Opcode(op);
			}
		} else {
			return inst;
		}
	} else {
		return inst;
	}
}
예제 #7
0
파일: MemMap.cpp 프로젝트: ANR2ME/ppsspp
Opcode Read_Opcode_JIT(u32 address)
{
	Opcode inst = Opcode(Read_U32(address));
	if (MIPS_IS_RUNBLOCK(inst.encoding) && MIPSComp::jit) {
		JitBlockCache *bc = MIPSComp::jit->GetBlockCache();
		int block_num = bc->GetBlockNumberFromEmuHackOp(inst, true);
		if (block_num >= 0) {
			return bc->GetOriginalFirstOp(block_num);
		} else {
			return inst;
		}
	} else {
		return inst;
	}
}
예제 #8
0
파일: MemMap.cpp 프로젝트: Carter07/ppsspp
Opcode Read_Instruction(u32 address)
{
	Opcode inst = Opcode(Read_U32(address));
	if (MIPS_IS_EMUHACK(inst) && MIPSComp::jit)
	{
		JitBlockCache *bc = MIPSComp::jit->GetBlockCache();
		int block_num = bc->GetBlockNumberFromEmuHackOp(inst);
		if (block_num >= 0) {
			return bc->GetOriginalFirstOp(block_num);
		} else {
			return inst;
		}
	} else {
		return inst;
	}
}
예제 #9
0
파일: MIPSAsm.cpp 프로젝트: Carter07/ppsspp
bool MipsAssembleOpcode(const char* line, DebugInterface* cpu, u32 address, u32& dest)
{
	char name[64],args[256];
	SplitLine(line,name,args);

	CMipsInstruction Opcode(cpu);
	if (cpu == NULL || Opcode.Load(name,args,(int)address) == false)
	{
		return false;
	}
	if (Opcode.Validate() == false)
	{
		return false;
	}

	Opcode.Encode();
	dest = Opcode.getEncoding();

	return true;
}
예제 #10
0
//------------------------------Value-----------------------------------------
const Type *MulNode::Value( PhaseTransform *phase ) const {
  const Type *t1 = phase->type( in(1) );
  const Type *t2 = phase->type( in(2) );
  // Either input is TOP ==> the result is TOP
  if( t1 == Type::TOP ) return Type::TOP;
  if( t2 == Type::TOP ) return Type::TOP;

  // Either input is ZERO ==> the result is ZERO.
  // Not valid for floats or doubles since +0.0 * -0.0 --> +0.0
  int op = Opcode();
  if( op == Op_MulI || op == Op_AndI || op == Op_MulL || op == Op_AndL ) {
    const Type *zero = add_id();        // The multiplicative zero
    if( t1->higher_equal( zero ) ) return zero;
    if( t2->higher_equal( zero ) ) return zero;
  }

  // Either input is BOTTOM ==> the result is the local BOTTOM
  if( t1 == Type::BOTTOM || t2 == Type::BOTTOM )
    return bottom_type();

  return mul_ring(t1,t2);            // Local flavor of type multiplication
}
예제 #11
0
//------------------------------Ideal------------------------------------------
Node *CmpDNode::Ideal(PhaseGVN *phase, bool can_reshape){
  // Check if we can change this to a CmpF and remove a ConvD2F operation.
  // Change  (CMPD (F2D (float)) (ConD value))
  // To      (CMPF      (float)  (ConF value))
  // Valid when 'value' does not lose precision as a float.
  // Benefits: eliminates conversion, does not require 24-bit mode

  // NaNs prevent commuting operands.  This transform works regardless of the 
  // order of ConD and ConvF2D inputs by preserving the original order.
  int idx_f2d = 1;              // ConvF2D on left side?
  if( in(idx_f2d)->Opcode() != Op_ConvF2D ) 
    idx_f2d = 2;                // No, swap to check for reversed args
  int idx_con = 3-idx_f2d;      // Check for the constant on other input

  if( ConvertCmpD2CmpF &&
      in(idx_f2d)->Opcode() == Op_ConvF2D &&
      in(idx_con)->Opcode() == Op_ConD ) {
    const TypeD *t2 = in(idx_con)->bottom_type()->is_double_constant();
    double t2_value_as_double = t2->_d;
    float  t2_value_as_float  = (float)t2_value_as_double;
    if( t2_value_as_double == (double)t2_value_as_float ) {
      // Test value can be represented as a float
      // Eliminate the conversion to double and create new comparison
      Node *new_in1 = in(idx_f2d)->in(1);
      Node *new_in2 = phase->makecon( TypeF::make(t2_value_as_float) );
      if( idx_f2d != 1 ) {      // Must flip args to match original order
        Node *tmp = new_in1;
        new_in1 = new_in2;
        new_in2 = tmp;
      }
      CmpFNode *new_cmp = (Opcode() == Op_CmpD3) 
        ? new (3) CmpF3Node( new_in1, new_in2 ) 
        : new (3) CmpFNode ( new_in1, new_in2 ) ;
      return new_cmp;           // Changed to CmpFNode
    }
    // Testing value required the precision of a double
  }
  return NULL;			// No change
}
예제 #12
0
파일: ir.cpp 프로젝트: Alienfeel/hhvm
Opcode getStackModifyingOpcode(Opcode opc) {
  assert(opcodeHasFlags(opc, HasStackVersion));
  opc = Opcode(uint64_t(opc) + 1);
  assert(opcodeHasFlags(opc, ModifiesStack));
  return opc;
}
예제 #13
0
void HiRes5Engine::setupOpcodeTables() {
	Common::Array<const Opcode *> *table = 0;

	SetOpcodeTable(_condOpcodes);
	// 0x00
	OpcodeUnImpl();
	Opcode(o2_isFirstTime);
	Opcode(o2_isRandomGT);
	Opcode(o4_isItemInRoom);
	// 0x04
	Opcode(o3_isNounNotInRoom);
	Opcode(o1_isMovesGT);
	Opcode(o1_isVarEQ);
	Opcode(o2_isCarryingSomething);
	// 0x08
	Opcode(o4_isVarGT);
	Opcode(o1_isCurPicEQ);
	OpcodeUnImpl();

	SetOpcodeTable(_actOpcodes);
	// 0x00
	OpcodeUnImpl();
	Opcode(o1_varAdd);
	Opcode(o1_varSub);
	Opcode(o1_varSet);
	// 0x04
	Opcode(o1_listInv);
	Opcode(o4_moveItem);
	Opcode(o1_setRoom);
	Opcode(o2_setCurPic);
	// 0x08
	Opcode(o2_setPic);
	Opcode(o1_printMsg);
	Opcode(o4_setRegionToPrev);
	Opcode(o_checkItemTimeLimits);
	// 0x0c
	Opcode(o4_moveAllItems);
	Opcode(o1_quit);
	Opcode(o4_setRegion);
	Opcode(o4_save);
	// 0x10
	Opcode(o4_restore);
	Opcode(o4_restart);
	Opcode(o4_setRegionRoom);
	Opcode(o_startAnimation);
	// 0x14
	Opcode(o1_resetPic);
	Opcode(o1_goDirection<IDI_DIR_NORTH>);
	Opcode(o1_goDirection<IDI_DIR_SOUTH>);
	Opcode(o1_goDirection<IDI_DIR_EAST>);
	// 0x18
	Opcode(o1_goDirection<IDI_DIR_WEST>);
	Opcode(o1_goDirection<IDI_DIR_UP>);
	Opcode(o1_goDirection<IDI_DIR_DOWN>);
	Opcode(o1_takeItem);
	// 0x1c
	Opcode(o1_dropItem);
	Opcode(o4_setRoomPic);
	Opcode(o_winGame);
	OpcodeUnImpl();
	// 0x20
	Opcode(o2_initDisk);
}
예제 #14
0
/* The bytecode interpreter for the NFA */
static int re_match(value re,
                    unsigned char * starttxt,
                    register unsigned char * txt,
                    register unsigned char * endtxt,
                    int accept_partial_match)
{
  register value * pc;
  intnat instr;
  struct backtrack_stack * stack;
  union backtrack_point * sp;
  value cpool;
  value normtable;
  unsigned char c;
  union backtrack_point back;

  { int i;
    struct re_group * p;
    unsigned char ** q;
    for (p = &re_group[1], i = Numgroups(re); i > 1; i--, p++)
      p->start = p->end = NULL;
    for (q = &re_register[0], i = Numregisters(re); i > 0; i--, q++)
      *q = NULL;
  }

  pc = &Field(Prog(re), 0);
  stack = &initial_stack;
  sp = stack->point;
  cpool = Cpool(re);
  normtable = Normtable(re);
  re_group[0].start = txt;

  while (1) {
    instr = Long_val(*pc++);
    switch (Opcode(instr)) {
    case CHAR:
      if (txt == endtxt) goto prefix_match;
      if (*txt != Arg(instr)) goto backtrack;
      txt++;
      break;
    case CHARNORM:
      if (txt == endtxt) goto prefix_match;
      if (Byte_u(normtable, *txt) != Arg(instr)) goto backtrack;
      txt++;
      break;
    case STRING: {
      unsigned char * s =
        (unsigned char *) String_val(Field(cpool, Arg(instr)));
      while ((c = *s++) != 0) {
        if (txt == endtxt) goto prefix_match;
        if (c != *txt) goto backtrack;
        txt++;
      }
      break;
    }
    case STRINGNORM: {
      unsigned char * s =
        (unsigned char *) String_val(Field(cpool, Arg(instr)));
      while ((c = *s++) != 0) {
        if (txt == endtxt) goto prefix_match;
        if (c != Byte_u(normtable, *txt)) goto backtrack;
        txt++;
      }
      break;
    }
    case CHARCLASS:
      if (txt == endtxt) goto prefix_match;
      if (! In_bitset(String_val(Field(cpool, Arg(instr))), *txt, c))
        goto backtrack;
      txt++;
      break;
    case BOL:
      if (txt > starttxt && txt[-1] != '\n') goto backtrack;
      break;
    case EOL:
      if (txt < endtxt && *txt != '\n') goto backtrack;
      break;
    case WORDBOUNDARY:
      /* At beginning and end of text: no
         At beginning of text: OK if current char is a letter
         At end of text: OK if previous char is a letter
         Otherwise:
           OK if previous char is a letter and current char not a letter
           or previous char is not a letter and current char is a letter */
      if (txt == starttxt) {
        if (txt == endtxt) goto prefix_match;
        if (Is_word_letter(txt[0])) break;
        goto backtrack;
      } else if (txt == endtxt) {
        if (Is_word_letter(txt[-1])) break;
        goto backtrack;
      } else {
        if (Is_word_letter(txt[-1]) != Is_word_letter(txt[0])) break;
        goto backtrack;
      }
    case BEGGROUP: {
      int group_no = Arg(instr);
      struct re_group * group = &(re_group[group_no]);
      back.undo.loc = &(group->start);
      back.undo.val = group->start;
      group->start = txt;
      goto push;
    }
    case ENDGROUP: {
      int group_no = Arg(instr);
      struct re_group * group = &(re_group[group_no]);
      back.undo.loc = &(group->end);
      back.undo.val = group->end;
      group->end = txt;
      goto push;
    }
    case REFGROUP: {
      int group_no = Arg(instr);
      struct re_group * group = &(re_group[group_no]);
      unsigned char * s;
      if (group->start == NULL || group->end == NULL) goto backtrack;
      for (s = group->start; s < group->end; s++) {
        if (txt == endtxt) goto prefix_match;
        if (*s != *txt) goto backtrack;
        txt++;
      }
      break;
    }
    case ACCEPT:
      goto accept;
    case SIMPLEOPT: {
      char * set = String_val(Field(cpool, Arg(instr)));
      if (txt < endtxt && In_bitset(set, *txt, c)) txt++;
      break;
    }
    case SIMPLESTAR: {
      char * set = String_val(Field(cpool, Arg(instr)));
      while (txt < endtxt && In_bitset(set, *txt, c))
        txt++;
      break;
    }
    case SIMPLEPLUS: {
      char * set = String_val(Field(cpool, Arg(instr)));
      if (txt == endtxt) goto prefix_match;
      if (! In_bitset(set, *txt, c)) goto backtrack;
      txt++;
      while (txt < endtxt && In_bitset(set, *txt, c))
        txt++;
      break;
    }
    case GOTO:
      pc = pc + SignedArg(instr);
      break;
    case PUSHBACK:
      back.pos.pc = Set_tag(pc + SignedArg(instr));
      back.pos.txt = txt;
      goto push;
    case SETMARK: {
      int reg_no = Arg(instr);
      unsigned char ** reg = &(re_register[reg_no]);
      back.undo.loc = reg;
      back.undo.val = *reg;
      *reg = txt;
      goto push;
    }
    case CHECKPROGRESS: {
      int reg_no = Arg(instr);
      if (re_register[reg_no] == txt)
        goto backtrack;
      break;
    }
    default:
      caml_fatal_error ("impossible case in re_match");
    }
    /* Continue with next instruction */
    continue;

  push:
    /* Push an item on the backtrack stack and continue with next instr */
    if (sp == stack->point + BACKTRACK_STACK_BLOCK_SIZE) {
      struct backtrack_stack * newstack =
        caml_stat_alloc(sizeof(struct backtrack_stack));
      newstack->previous = stack;
      stack = newstack;
      sp = stack->point;
    }
    *sp = back;
    sp++;
    continue;

  prefix_match:
    /* We get here when matching failed because the end of text
       was encountered. */
    if (accept_partial_match) goto accept;

  backtrack:
    /* We get here when matching fails.  Backtrack to most recent saved
       program point, undoing variable assignments on the way. */
    while (1) {
      if (sp == stack->point) {
        struct backtrack_stack * prevstack = stack->previous;
        if (prevstack == NULL) return 0;
        caml_stat_free(stack);
        stack = prevstack;
        sp = stack->point + BACKTRACK_STACK_BLOCK_SIZE;
      }
      sp--;
      if (Tag_is_set(sp->pos.pc)) {
        pc = Clear_tag(sp->pos.pc);
        txt = sp->pos.txt;
        break;
      } else {
        *(sp->undo.loc) = sp->undo.val;
      }
    }
    continue;
  }

 accept:
  /* We get here when the regexp was successfully matched */
  free_backtrack_stack(stack);
  re_group[0].end = txt;
  return 1;
}
예제 #15
0
bool KoEnhancedPathFormula::compile( const TokenList & tokens )
{
    // sanity check
    if( tokens.count() == 0 )
        return false;

    FormulaTokenStack syntaxStack;
    QStack<int> argStack;
    unsigned argCount = 1;

    for( int i = 0; i <= tokens.count(); i++ )
    {
        // helper token: InvalidOp is end-of-formula
        FormulaToken token =  ( i < tokens.count() ) ? tokens[i] : FormulaToken( FormulaToken::TypeOperator );
        FormulaToken::Type tokenType = token.type();

        // unknown token is invalid
        if( tokenType == FormulaToken::TypeUnknown )
            break;

        // for constants, push immediately to stack
        // generate code to load from a constant
        if( tokenType == FormulaToken::TypeNumber )
        {
            syntaxStack.push( token );
            m_constants.append( QVariant( token.asNumber() ) );
            m_codes.append( Opcode( Opcode::Load, m_constants.count()-1 ) );
        }
        // for identifier, push immediately to stack
        // generate code to load from reference
        if( tokenType == FormulaToken::TypeFunction || tokenType == FormulaToken::TypeReference )
        {
            syntaxStack.push( token );
            m_constants.append( QVariant( token.text() ) );
            m_codes.append( Opcode( Opcode::Ref, m_constants.count()-1 ) );
        }
        // are we entering a function ?
        // if token is operator, and stack already has: id ( arg
        if( tokenType == FormulaToken::TypeOperator && syntaxStack.itemCount() >= 3 )
        {
            FormulaToken arg = syntaxStack.top();
            FormulaToken par = syntaxStack.top( 1 );
            FormulaToken id = syntaxStack.top( 2 );
            if( !arg.isOperator() &&
                 par.asOperator() == FormulaToken::OperatorLeftPar &&
                 id.isFunction() )
            {
                argStack.push( argCount );
                argCount = 1;
            }
        }
        // for any other operator, try to apply all parsing rules
        if( tokenType == FormulaToken::TypeOperator )
        {
            // repeat until no more rule applies
            for( ; ; )
            {
                bool ruleFound = false;

                // rule for function arguments, if token is , or )
                // id ( arg1 , arg2 -> id ( arg
                if( !ruleFound )
                if( syntaxStack.itemCount() >= 5 )
                if( ( token.asOperator() == FormulaToken::OperatorRightPar ) ||
                    ( token.asOperator() == FormulaToken::OperatorComma ) )
                {
                    FormulaToken arg2 = syntaxStack.top();
                    FormulaToken sep = syntaxStack.top( 1 );
                    FormulaToken arg1 = syntaxStack.top( 2 );
                    FormulaToken par = syntaxStack.top( 3 );
                    FormulaToken id = syntaxStack.top( 4 );
                    if( !arg2.isOperator() )
                    if( sep.asOperator() == FormulaToken::OperatorComma )
                    if( !arg1.isOperator() )
                    if( par.asOperator() == FormulaToken::OperatorLeftPar )
                    if( id.isFunction() )
                    {
                        ruleFound = true;
                        syntaxStack.pop();
                        syntaxStack.pop();
                        argCount++;
                    }
                }
                // rule for function last argument:
                //  id ( arg ) -> arg
                if( !ruleFound )
                if( syntaxStack.itemCount() >= 4 )
                {
                    FormulaToken par2 = syntaxStack.top();
                    FormulaToken arg = syntaxStack.top( 1 );
                    FormulaToken par1 = syntaxStack.top( 2 );
                    FormulaToken id = syntaxStack.top( 3 );
                    if( par2.asOperator() == FormulaToken::OperatorRightPar )
                    if( !arg.isOperator() )
                    if( par1.asOperator() == FormulaToken::OperatorLeftPar )
                    if( id.isFunction() )
                    {
                        ruleFound = true;
                        syntaxStack.pop();
                        syntaxStack.pop();
                        syntaxStack.pop();
                        syntaxStack.pop();
                        syntaxStack.push( arg );
                        m_codes.append( Opcode( Opcode::Function, argCount ) );
                        argCount = argStack.empty() ? 0 : argStack.pop();
                    }
                }

                // rule for parenthesis:  ( Y ) -> Y
                if( !ruleFound )
                if( syntaxStack.itemCount() >= 3 )
                {
                    FormulaToken right = syntaxStack.top();
                    FormulaToken y = syntaxStack.top( 1 );
                    FormulaToken left = syntaxStack.top( 2 );
                    if( right.isOperator() )
                    if( !y.isOperator() )
                    if( left.isOperator() )
                    if( right.asOperator() == FormulaToken::OperatorRightPar )
                    if( left.asOperator() == FormulaToken::OperatorLeftPar )
                    {
                        ruleFound = true;
                        syntaxStack.pop();
                        syntaxStack.pop();
                        syntaxStack.pop();
                        syntaxStack.push( y );
                    }
                }

                // rule for binary operator:  A (op) B -> A
                // conditions: precedence of op >= precedence of token
                // action: push (op) to result
                // e.g. "A * B" becomes 'A' if token is operator '+'
                if( !ruleFound )
                if( syntaxStack.itemCount() >= 3 )
                {
                    FormulaToken b = syntaxStack.top();
                    FormulaToken op = syntaxStack.top( 1 );
                    FormulaToken a = syntaxStack.top( 2 );
                    if( !a.isOperator() )
                    if( !b.isOperator() )
                    if( op.isOperator() )
                    if( token.asOperator() != FormulaToken::OperatorLeftPar )
                    if( opPrecedence( op.asOperator() ) >= opPrecedence( token.asOperator() ) )
                    {
                        ruleFound = true;
                        syntaxStack.pop();
                        syntaxStack.pop();
                        syntaxStack.pop();
                        syntaxStack.push( b );
                        switch( op.asOperator() )
                        {
                            // simple binary operations
                            case FormulaToken::OperatorAdd: m_codes.append( Opcode::Add ); break;
                            case FormulaToken::OperatorSub: m_codes.append( Opcode::Sub ); break;
                            case FormulaToken::OperatorMul: m_codes.append( Opcode::Mul ); break;
                            case FormulaToken::OperatorDiv: m_codes.append( Opcode::Div ); break;
                            default: break;
                        };
                    }
                }

                // rule for unary operator:  (op1) (op2) X -> (op1) X
                // conditions: op2 is unary, token is not '('
                // action: push (op2) to result
                // e.g.  "* - 2" becomes '*'
                if( !ruleFound )
                if( token.asOperator() != FormulaToken::OperatorLeftPar )
                if( syntaxStack.itemCount() >= 3 )
                {
                    FormulaToken x = syntaxStack.top();
                    FormulaToken op2 = syntaxStack.top( 1 );
                    FormulaToken op1 = syntaxStack.top( 2 );
                    if( !x.isOperator() )
                    if( op1.isOperator() )
                    if( op2.isOperator() )
                    if( ( op2.asOperator() == FormulaToken::OperatorAdd ) ||
                    ( op2.asOperator() == FormulaToken::OperatorSub ) )
                    {
                        ruleFound = true;
                        syntaxStack.pop();
                        syntaxStack.pop();
                        syntaxStack.push( x );
                        if( op2.asOperator() == FormulaToken::OperatorSub )
                            m_codes.append( Opcode( Opcode::Neg ) );
                    }
                }

                // auxiliary rule for unary operator:  (op) X -> X
                // conditions: op is unary, op is first in syntax stack, token is not '('
                // action: push (op) to result
                if( !ruleFound )
                if( token.asOperator() != FormulaToken::OperatorLeftPar )
                if( syntaxStack.itemCount() == 2 )
                {
                    FormulaToken x = syntaxStack.top();
                    FormulaToken op = syntaxStack.top( 1 );
                    if( !x.isOperator() )
                    if( op.isOperator() )
                    if( ( op.asOperator() == FormulaToken::OperatorAdd ) ||
                    ( op.asOperator() == FormulaToken::OperatorSub ) )
                    {
                        ruleFound = true;
                        syntaxStack.pop();
                        syntaxStack.pop();
                        syntaxStack.push( x );
                        if( op.asOperator() == FormulaToken::OperatorSub )
                            m_codes.append( Opcode( Opcode::Neg ) );
                    }
                }

                if( !ruleFound )
                    break;
            }

            syntaxStack.push( token );
        }
    }

    // syntaxStack must left only one operand and end-of-formula (i.e. InvalidOp)
    m_valid = false;
    if( syntaxStack.itemCount() == 2 )
    if( syntaxStack.top().isOperator() )
    if( syntaxStack.top().asOperator() == FormulaToken::OperatorInvalid )
    if( !syntaxStack.top(1).isOperator() )
        m_valid = true;

    // bad parsing ? clean-up everything
    if( ! m_valid )
    {
        m_constants.clear();
        m_codes.clear();
        kWarning() << "compiling of "<< m_text << " failed";
    }

    return m_valid;
}
예제 #16
0
//=============================================================================
//------------------------------hash-------------------------------------------
// Hash function over AddNodes.  Needs to be commutative; i.e., I swap
// (commute) inputs to AddNodes willy-nilly so the hash function must return
// the same value in the presence of edge swapping.
uint AddNode::hash() const {
  return (uintptr_t)in(1) + (uintptr_t)in(2) + Opcode();
}
예제 #17
0
void AdlEngine_v2::setupOpcodeTables() {
	Common::Array<const Opcode *> *table = 0;

	SetOpcodeTable(_condOpcodes);
	// 0x00
	OpcodeUnImpl();
	Opcode(o2_isFirstTime);
	Opcode(o2_isRandomGT);
	Opcode(o1_isItemInRoom);
	// 0x04
	Opcode(o2_isNounNotInRoom);
	Opcode(o1_isMovesGT);
	Opcode(o1_isVarEQ);
	Opcode(o2_isCarryingSomething);
	// 0x08
	OpcodeUnImpl();
	Opcode(o1_isCurPicEQ);
	Opcode(o1_isItemPicEQ);

	SetOpcodeTable(_actOpcodes);
	// 0x00
	OpcodeUnImpl();
	Opcode(o1_varAdd);
	Opcode(o1_varSub);
	Opcode(o1_varSet);
	// 0x04
	Opcode(o1_listInv);
	Opcode(o2_moveItem);
	Opcode(o1_setRoom);
	Opcode(o2_setCurPic);
	// 0x08
	Opcode(o2_setPic);
	Opcode(o1_printMsg);
	Opcode(o1_setLight);
	Opcode(o1_setDark);
	// 0x0c
	Opcode(o2_moveAllItems);
	Opcode(o1_quit);
	OpcodeUnImpl();
	Opcode(o2_save);
	// 0x10
	Opcode(o2_restore);
	Opcode(o1_restart);
	Opcode(o2_placeItem);
	Opcode(o1_setItemPic);
	// 0x14
	Opcode(o1_resetPic);
	Opcode(o1_goDirection<IDI_DIR_NORTH>);
	Opcode(o1_goDirection<IDI_DIR_SOUTH>);
	Opcode(o1_goDirection<IDI_DIR_EAST>);
	// 0x18
	Opcode(o1_goDirection<IDI_DIR_WEST>);
	Opcode(o1_goDirection<IDI_DIR_UP>);
	Opcode(o1_goDirection<IDI_DIR_DOWN>);
	Opcode(o1_takeItem);
	// 0x1c
	Opcode(o1_dropItem);
	Opcode(o1_setRoomPic);
	Opcode(o2_tellTime);
	Opcode(o2_setRoomFromVar);
	// 0x20
	Opcode(o2_initDisk);
}
예제 #18
0
//------------------------------Idealize---------------------------------------
// If we get here, we assume we are associative!
Node *AddNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  const Type *t1 = phase->type( in(1) );
  const Type *t2 = phase->type( in(2) );
  int con_left  = t1->singleton();
  int con_right = t2->singleton();

  // Check for commutative operation desired
  if( commute(this,con_left,con_right) ) return this;

  AddNode *progress = NULL;             // Progress flag

  // Convert "(x+1)+2" into "x+(1+2)".  If the right input is a
  // constant, and the left input is an add of a constant, flatten the
  // expression tree.
  Node *add1 = in(1);
  Node *add2 = in(2);
  int add1_op = add1->Opcode();
  int this_op = Opcode();
  if( con_right && t2 != Type::TOP && // Right input is a constant?
      add1_op == this_op ) { // Left input is an Add?

    // Type of left _in right input
    const Type *t12 = phase->type( add1->in(2) );
    if( t12->singleton() && t12 != Type::TOP ) { // Left input is an add of a constant?
      // Check for rare case of closed data cycle which can happen inside
      // unreachable loops. In these cases the computation is undefined.
#ifdef ASSERT
      Node *add11    = add1->in(1);
      int   add11_op = add11->Opcode();
      if( (add1 == add1->in(1))
         || (add11_op == this_op && add11->in(1) == add1) ) {
        assert(false, "dead loop in AddNode::Ideal");
      }
#endif
      // The Add of the flattened expression
      Node *x1 = add1->in(1);
      Node *x2 = phase->makecon( add1->as_Add()->add_ring( t2, t12 ));
      PhaseIterGVN *igvn = phase->is_IterGVN();
      if( igvn ) {
        set_req_X(2,x2,igvn);
        set_req_X(1,x1,igvn);
      } else {
        set_req(2,x2);
        set_req(1,x1);
      }
      progress = this;            // Made progress
      add1 = in(1);
      add1_op = add1->Opcode();
    }
  }

  // Convert "(x+1)+y" into "(x+y)+1".  Push constants down the expression tree.
  if( add1_op == this_op && !con_right ) {
    Node *a12 = add1->in(2);
    const Type *t12 = phase->type( a12 );
    if( t12->singleton() && t12 != Type::TOP && (add1 != add1->in(1)) &&
       !(add1->in(1)->is_Phi() && add1->in(1)->as_Phi()->is_tripcount()) ) {
      assert(add1->in(1) != this, "dead loop in AddNode::Ideal");
      add2 = add1->clone();
      add2->set_req(2, in(2));
      add2 = phase->transform(add2);
      set_req(1, add2);
      set_req(2, a12);
      progress = this;
      add2 = a12;
    }
  }

  // Convert "x+(y+1)" into "(x+y)+1".  Push constants down the expression tree.
  int add2_op = add2->Opcode();
  if( add2_op == this_op && !con_left ) {
    Node *a22 = add2->in(2);
    const Type *t22 = phase->type( a22 );
    if( t22->singleton() && t22 != Type::TOP && (add2 != add2->in(1)) &&
       !(add2->in(1)->is_Phi() && add2->in(1)->as_Phi()->is_tripcount()) ) {
      assert(add2->in(1) != this, "dead loop in AddNode::Ideal");
      Node *addx = add2->clone();
      addx->set_req(1, in(1));
      addx->set_req(2, add2->in(1));
      addx = phase->transform(addx);
      set_req(1, addx);
      set_req(2, a22);
      progress = this;
      PhaseIterGVN *igvn = phase->is_IterGVN();
      if (add2->outcnt() == 0 && igvn) {
        // add disconnected.
        igvn->_worklist.push(add2);
      }
    }
  }

  return progress;
}
예제 #19
0
Optab::Optab()
{
	for (int i=0; i<NUM_OP; ++i)
		insert(Opcode(oprecord[i].mnem, oprecord[i].opcode, oprecord[i].format));
}
예제 #20
0
//------------------------------Ideal------------------------------------------
// We also canonicalize the Node, moving constants to the right input, 
// and flatten expressions (so that 1+x+2 becomes x+3).
Node *MulNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  const Type *t1 = phase->type( in(1) );
  const Type *t2 = phase->type( in(2) );
  Node *progress = NULL;        // Progress flag
  // We are OK if right is a constant, or right is a load and
  // left is a non-constant.
  if( !(t2->singleton() ||
        (in(2)->is_Load() && !(t1->singleton() || in(1)->is_Load())) ) ) {
    if( t1->singleton() ||       // Left input is a constant?
        // Otherwise, sort inputs (commutativity) to help value numbering.
        (in(1)->_idx > in(2)->_idx) ) {
      swap_edges(1, 2);
      const Type *t = t1;
      t1 = t2;
      t2 = t;
      progress = this;            // Made progress
    }
  }

  // If the right input is a constant, and the left input is a product of a
  // constant, flatten the expression tree.
  uint op = Opcode();
  if( t2->singleton() &&        // Right input is a constant?
      op != Op_MulF &&          // Float & double cannot reassociate
      op != Op_MulD ) { 
    if( t2 == Type::TOP ) return NULL;
    Node *mul1 = in(1);
    if( mul1 == this ) {        // Check for dead cycle
      set_req(1, phase->C->top());
      return this;              // Make it trivially dead
    }
    if( mul1->Opcode() == mul_opcode() ) {  // Left input is a multiply?
      // Mul of a constant?
      const Type *t12 = phase->type( mul1->in(2) ); 
      if( t12->singleton() && t12 != Type::TOP) { // Left input is an add of a constant?
        // Compute new constant; check for overflow
        const Type *tcon01 = mul1->is_Mul()->mul_ring(t2,t12);
        if( tcon01->singleton() ) {
          // The Mul of the flattened expression
          set_req(1, mul1->in(1));
          set_req(2, phase->makecon( tcon01 ));
          t2 = tcon01;
          progress = this;      // Made progress
        }
      }
    }
    // If the right input is a constant, and the left input is an add of a 
    // constant, flatten the tree: (X+con1)*con0 ==> X*con0 + con1*con0
    const Node *add1 = in(1);
    if( add1->Opcode() == add_opcode() ) {      // Left input is an add?
      // Add of a constant?
      const Type *t12 = phase->type( add1->in(2) ); 
      if( t12->singleton() && t12 != Type::TOP ) { // Left input is an add of a constant?
        // Check if the add node is dead and self-referencing, 
        // to avoid infinite loop (no progress).
        if( add1->in(1) == add1 ) return progress;
        // Compute new constant; check for overflow
        const Type *tcon01 = mul_ring(t2,t12);
        if( tcon01->singleton() ) {
        
        // Convert (X+con1)*con0 into X*con0
          Node *mul = clone();    // mul = ()*con0
          mul->set_req(1,add1->in(1));  // mul = X*con0
          mul = phase->transform(mul);

          Node *add2 = add1->clone();
          add2->set_req(1, mul);        // X*con0 + con0*con1
          add2->set_req(2, phase->makecon(tcon01) );
          progress = add2;
        }
      }
    } // End of is left input an add
  } // End of is right input a Mul

  return progress;
}
예제 #21
0
void exec(Um_code * code) {
  Um_code ** platters = malloc(sizeof(*platters) * DEFAULT_PLATTERS);
  unsigned int pc = 0;
  platters[0] = code;
  unsigned int current_word;
  unsigned int registers[8] = { 0 };
  unsigned int next_allocate = 1;
  unsigned int allocate_max = DEFAULT_PLATTERS;
  Free_Queue * spaces = NULL;
  for (;;) {
    current_word = platters[0]->code[pc++];
    switch (Opcode(current_word)) {
    case CMV:
      debug("Conditional move");
      if (registers[WORDC] != 0) {
	registers[WORDA] = registers[WORDB];
      }
      break;
    case AIND:
      debug("Array Index");
      registers[WORDA] = platters[registers[WORDB]]->code[registers[WORDC]];
      break;
    case AAMD:
      debug("Array amendment");
      if (platters[registers[WORDA]] == NULL) {
	fprintf(stderr, "null\n");
      }
      platters[registers[WORDA]]->code[registers[WORDB]] = registers[WORDC];
      break;
    case ADD:
      debug("Addition");
      registers[WORDA] = registers[WORDB] + registers[WORDC];
      break;
    case MUL:
      debug("Multiplication");
      registers[WORDA] = registers[WORDB] * registers[WORDC];
      break;
    case DIV:
      debug("Division");
      if (registers[WORDC])
	registers[WORDA] = registers[WORDB] / registers[WORDC];
      break;
    case NAND:
      debug("Not-And");
      registers[WORDA] = ~(registers[WORDB] & registers[WORDC]);
      break;
    case HALT:
      debug("Halt");
      destroyFreeQueue(spaces);
      for (unsigned int i = 0; i < allocate_max; i++)
	destroyCode(platters[i]);
      free(platters);
      exit(1);
      break;
    case ALLOC:
      debug("Allocation");
      unsigned int size = registers[WORDC];
      unsigned int position = 0;
      Um_code * new_platter = malloc(sizeof *new_platter);
      new_platter->code = calloc(size, 4);
      new_platter->int_size = size;
      if (spaces != NULL) {
	position = popEltValue(&spaces);
      } else {
	if (next_allocate >= allocate_max) {
	  position = allocate_max;
	  allocate_max *= 2;
	  platters = realloc_and_copy(platters, allocate_max/2, allocate_max);
	  next_allocate++;
	} else {
	  position = next_allocate++;
	}
      }
      platters[position] = new_platter;
      registers[WORDB] = position;
      break;
    case ABDN:
      debug("Abandonment");
      free(platters[registers[WORDC]]);
      platters[registers[WORDC]] = NULL;
      pushValue(&spaces, registers[WORDC]);
      break;
    case OUT:
      debug("Output");
      unsigned char cout = registers[WORDC];
      fprintf(stdout, "%c", cout);
      break;
    case IN:
      debug("Input");
      unsigned char cin;
      int dummy = scanf("%c", &cin);
      if (cin == EOF)
	registers[WORDC] = 0xFFFFFFFF;
      else
	registers[WORDC] = cin;
      break;
    case LPRO:
      // Seg fault @ LPRO 7 7 0
      debug("Load program");
      if (registers[WORDB] != 0) {
	Um_code * src = platters[registers[WORDB]];
	Um_code * dest = malloc(sizeof(*dest));
	dest->code = calloc(src->int_size, 4);
	memcpy(dest->code, src->code, src->int_size * 4);
	dest->int_size = src->int_size;
	destroyCode(platters[0]);
	platters[0] = dest;
      }
      pc = registers[WORDC];
      break;
    case ORTH:
      debug("Orthography");
      unsigned int imd = current_word & 0x01FFFFFF;
      unsigned int a = (current_word >> 25) & 0x07;
      registers[a] = imd;
      break;
    default:
      debug("Unkown operand");
      break;
    }
  }
}
예제 #22
0
파일: MemMap.cpp 프로젝트: ANR2ME/ppsspp
Opcode ReadUnchecked_Instruction(u32 address, bool resolveReplacements)
{
	Opcode inst = Opcode(ReadUnchecked_U32(address));
	return Read_Instruction(address, resolveReplacements, inst);
}