/* 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; } }
//============================================================================= //------------------------------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; }
//------------------------------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; }
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; } }
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; } }
__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; } }
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; } }
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; } }
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; }
//------------------------------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 }
//------------------------------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 }
Opcode getStackModifyingOpcode(Opcode opc) { assert(opcodeHasFlags(opc, HasStackVersion)); opc = Opcode(uint64_t(opc) + 1); assert(opcodeHasFlags(opc, ModifiesStack)); return opc; }
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); }
/* 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; }
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; }
//============================================================================= //------------------------------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(); }
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); }
//------------------------------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; }
Optab::Optab() { for (int i=0; i<NUM_OP; ++i) insert(Opcode(oprecord[i].mnem, oprecord[i].opcode, oprecord[i].format)); }
//------------------------------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; }
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; } } }
Opcode ReadUnchecked_Instruction(u32 address, bool resolveReplacements) { Opcode inst = Opcode(ReadUnchecked_U32(address)); return Read_Instruction(address, resolveReplacements, inst); }