コード例 #1
0
void ODSItemState :: ResetState ( )
{

  ResetValue();
  ResetList();

}
コード例 #2
0
ファイル: ObjectEntry.cpp プロジェクト: RIVeR-Lab/eposcmd
CObjectEntry& CObjectEntry::operator=(CObjectEntry& other)
{
    if(this != &other)
    {
        *((CObjectEntryBase*)this) = *((CObjectEntryBase*)&other);

        m_uSubIndex = other.m_uSubIndex;
        m_DataType = other.m_DataType;
        m_AccessType = other.m_AccessType;
        m_oPDOMapping = other.m_oPDOMapping;
        m_strLowLimit = other.m_strLowLimit;
        m_strHighLimit = other.m_strHighLimit;
        m_strDefault = other.m_strDefault;
        m_strObjFlags = other.m_strObjFlags;
        m_ValueStringFormat = other.m_ValueStringFormat;
        //TODO:CHHE091209Can be serialised as soon as DtmEpos and DtmEsam also use this OBD classes
        //m_Denotation = other.m_Denotation;
        //m_UniqueId = other.m_UniqueId;

		ResetValue();
        if(other.m_dValueSize > 0)
        {
            m_pValue = (BYTE*)malloc(other.m_dValueSize);
            m_dValueSize = other.m_dValueSize;
            memcpy(m_pValue, other.m_pValue, other.m_dValueSize);
        }
    }

    return *this;
}
コード例 #3
0
ExecReturnCodes OPSynCase :: Execute ( )
{
  int32              indx0 = 0;
  ExecReturnCodes    rc    = ERC_undefined;

BEGINSEQ
  if ( CheckCO() )                                   ERROR
  
  if ( (block_type == CB_CaseBlock) )
  {
    if ( !source )                                   OQLSERR(99)
    if ( ExecuteParameter(0) != ERC_success )        ERROR
    
    if ( *source->GetValue() != *Parmlist()->GetAt(0)->GetValue() )
                                                     LEAVESEQ
    indx0 = 1;
  }
  if ( (rc = ExecuteStatements(indx0)) == ERC_undefined ) // no statements in case
    rc = ERC_success;
  RegisterLastValue();
RECOVER
  ResetValue();
  rc = ERC_terminate;
ENDSEQ
  return(rc);
}
コード例 #4
0
ExecReturnCodes OPSynWhile :: Execute ( )
{
  ExecReturnCodes    rc = ERC_undefined;
BEGINSEQ
  if ( CheckCO() )                                   ERROR
  
  while ( (rc = ExecuteSource()) == ERC_success )
  {
    if ( !source->GetValue()->IsTrue() )             LEAVESEQ
    switch ( rc = ExecuteStatement(0) )
    {
      case ERC_terminate :                           ERROR
      case ERC_null      :
      case ERC_success   :                           break;
      case ERC_undefined : // no statements
      case ERC_continue  : rc = ERC_success;         break;
      case ERC_break     : rc = ERC_success; 
      default            :                           LEAVESEQ
    }    
  }


RECOVER
  ResetValue();
  rc = ERC_terminate;
ENDSEQ
  if ( rc != ERC_terminate )
    RegisterLastValue();
  return(rc);
}
コード例 #5
0
ファイル: ObjectEntry.cpp プロジェクト: RIVeR-Lab/eposcmd
BOOL CObjectEntry::SetValue(BYTE* pValue, DWORD dValueSize)
{
    BOOL oResult(FALSE);

    ResetValue();
    if(InitValue(dValueSize))
    {
        memcpy(m_pValue, pValue, dValueSize);
        oResult = TRUE;
    }

    return oResult;
}
コード例 #6
0
ファイル: ObjectEntry.cpp プロジェクト: RIVeR-Lab/eposcmd
BOOL CObjectEntry::InitValue(DWORD dSize)
{
    BOOL oResult(FALSE);

    ResetValue();
    if(dSize > 0)
    {
        m_dValueSize = dSize;
        m_pValue = (BYTE*)malloc(m_dValueSize);
        memset(m_pValue, 0, m_dValueSize);
        oResult = TRUE;
    }

    return oResult;
}
コード例 #7
0
TEST_F(PropertiesTest, GetString) {

    // Try to use a default value that's too long => set fails
    {
        ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));

        std::string maxLengthString = std::string(PROPERTY_VALUE_MAX-1, 'a');
        std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');

        // Expect that the value is truncated since it's too long (by 1)
        int len = property_get(PROPERTY_TEST_KEY, mValue, oneLongerString.c_str());
        EXPECT_EQ(PROPERTY_VALUE_MAX-1, len);
        EXPECT_STREQ(maxLengthString.c_str(), mValue);
        ResetValue();
    }
}
コード例 #8
0
ファイル: ObjectEntry.cpp プロジェクト: RIVeR-Lab/eposcmd
BOOL CObjectEntry::Reset()
{
    BOOL oResult(TRUE);

    CObjectEntryBase::Reset();

    m_AccessType = AT_READ_ONLY;
    m_DataType = ODT_UNKNOWN;
    m_ValueStringFormat = OVF_HEX;
    m_oPDOMapping = 0;
    m_strDefault = _T("");
    m_strHighLimit = _T("");
    m_strLowLimit = _T("");
    m_strObjFlags = _T("0");
    m_uSubIndex = 0;

    if(!ResetValue()) oResult = FALSE;

    return oResult;
}
コード例 #9
0
ファイル: ObjectEntry.cpp プロジェクト: RIVeR-Lab/eposcmd
BOOL CObjectEntry::SetValue(CStdString strValue)
{
    CMmcDataConversion conversion;
    BOOL oResult(FALSE);

    //Reset
    ResetValue();

    //SetValue
    switch(m_DataType)
    {
        case ODT_BOOLEAN:
            {
                if(InitValue(sizeof(WORD)))
                {
                    if(strValue.CompareNoCase("TRUE") == 0)
                    {
                        *((WORD*)m_pValue) = TRUE;
                        oResult = TRUE;
                    }
                    else
                    {
                        *((WORD*)m_pValue) = FALSE;
                        oResult = TRUE;
                    }
                }
            };break;

        case ODT_INT8:
            {
                if(InitValue(sizeof(char)))
                {
                    oResult = conversion.CharStr2Char(strValue, ((char*)m_pValue), FALSE);
                }
            };break;
        case ODT_INT16:
            {
                if(InitValue(sizeof(short)))
                {
                    oResult = conversion.ShortStr2Short(strValue, ((short*)m_pValue), FALSE);
                }
            };break;
        case ODT_INT32:
            {
                if(InitValue(sizeof(long)))
                {
                    oResult = conversion.LongStr2Long(strValue, ((long*)m_pValue), FALSE);
                }
            };break;
        case ODT_INT64:
            {
                if(InitValue(sizeof(__int64)))
                {
                    oResult = conversion.Int64Str2Int64(strValue, ((__int64*)m_pValue), FALSE);
                }
            };break;
        case ODT_UINT8:
            {
                if(InitValue(sizeof(BYTE)))
                {
                    oResult = conversion.ByteStr2Byte(strValue, ((BYTE*)m_pValue), FALSE);
                }
            };break;
        case ODT_UINT16:
            {
                if(InitValue(sizeof(WORD)))
                {
                    oResult = conversion.WordStr2Word(strValue, ((WORD*)m_pValue));
                }
            };break;
        case ODT_UINT32:
            {
                if(InitValue(sizeof(DWORD)))
                {
                    oResult = conversion.DWordStr2DWord(strValue, ((DWORD*)m_pValue), FALSE);
                }
            };break;
        case ODT_UINT64:
            {
                if(InitValue(sizeof(unsigned __int64)))
                {
                    oResult = conversion.UInt64Str2UInt64(strValue, ((unsigned __int64*)m_pValue), FALSE);
                }
            };break;
        case ODT_FLOAT:
            {
                if(InitValue(sizeof(float)))
                {
                    oResult = conversion.FloatStr2Float(strValue, ((float*)m_pValue), FALSE);
                }
            };break;
        case ODT_STRING:
            {
                if(InitValue(strlen(strValue))*sizeof(TCHAR))
                {
                    for(DWORD d=0;d<m_dValueSize;d++)
                    {
                        *((TCHAR*)m_pValue+d) = strValue.GetAt(d);
                    }
                    oResult = TRUE;
                }
            };break;
    }

    return oResult;
}
コード例 #10
0
ファイル: ObjectEntry.cpp プロジェクト: RIVeR-Lab/eposcmd
CObjectEntry::~CObjectEntry()
{
    ResetValue();
}
コード例 #11
0
TEST_F(PropertiesTest, SetString) {

    // Null key -> unsuccessful set
    {
        // Null key -> fails
        EXPECT_GT(0, property_set(/*key*/NULL, PROPERTY_TEST_VALUE_DEFAULT));
    }

    // Null value -> returns default value
    {
        // Null value -> OK , and it clears the value
        EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL));
        ResetValue();

        // Since the value is null, default value will be returned
        size_t len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);
        EXPECT_EQ(strlen(PROPERTY_TEST_VALUE_DEFAULT), len);
        EXPECT_STREQ(PROPERTY_TEST_VALUE_DEFAULT, mValue);
    }

    // Trivial case => get returns what was set
    {
        size_t len = SetAndGetProperty("hello_world");
        EXPECT_EQ(strlen("hello_world"), len) << "hello_world key";
        EXPECT_STREQ("hello_world", mValue);
        ResetValue();
    }

    // Set to empty string => get returns default always
    {
        const char* EMPTY_STRING_DEFAULT = "EMPTY_STRING";
        size_t len = SetAndGetProperty("", EMPTY_STRING_DEFAULT);
        EXPECT_EQ(strlen(EMPTY_STRING_DEFAULT), len) << "empty key";
        EXPECT_STREQ(EMPTY_STRING_DEFAULT, mValue);
        ResetValue();
    }

    // Set to max length => get returns what was set
    {
        std::string maxLengthString = std::string(PROPERTY_VALUE_MAX-1, 'a');

        int len = SetAndGetProperty(maxLengthString.c_str());
        EXPECT_EQ(PROPERTY_VALUE_MAX-1, len) << "max length key";
        EXPECT_STREQ(maxLengthString.c_str(), mValue);
        ResetValue();
    }

    // Set to max length + 1 => set fails
    {
        const char* VALID_TEST_VALUE = "VALID_VALUE";
        ASSERT_OK(property_set(PROPERTY_TEST_KEY, VALID_TEST_VALUE));

        std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');

        // Expect that the value set fails since it's too long
        EXPECT_GT(0, property_set(PROPERTY_TEST_KEY, oneLongerString.c_str()));
        size_t len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);

        EXPECT_EQ(strlen(VALID_TEST_VALUE), len) << "set should've failed";
        EXPECT_STREQ(VALID_TEST_VALUE, mValue);
        ResetValue();
    }
}
コード例 #12
0
TEST_F(PropertiesTest, GetString) {

    // Try to use a default value that's too long => get truncates the value
    {
        ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));

        std::string maxLengthString = std::string(PROPERTY_VALUE_MAX - 1, 'a');
        std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');

        // Expect that the value is truncated since it's too long (by 1)
        int len = property_get(PROPERTY_TEST_KEY, mValue, oneLongerString.c_str());
        EXPECT_EQ(PROPERTY_VALUE_MAX - 1, len);
        EXPECT_STREQ(maxLengthString.c_str(), mValue);
        ResetValue();
    }

    // Try to use a default value that's the max length => get succeeds
    {
        ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));

        std::string maxLengthString = std::string(PROPERTY_VALUE_MAX - 1, 'b');

        // Expect that the value matches maxLengthString
        int len = property_get(PROPERTY_TEST_KEY, mValue, maxLengthString.c_str());
        EXPECT_EQ(PROPERTY_VALUE_MAX - 1, len);
        EXPECT_STREQ(maxLengthString.c_str(), mValue);
        ResetValue();
    }

    // Try to use a default value of length one => get succeeds
    {
        ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));

        std::string oneCharString = std::string(1, 'c');

        // Expect that the value matches oneCharString
        int len = property_get(PROPERTY_TEST_KEY, mValue, oneCharString.c_str());
        EXPECT_EQ(1, len);
        EXPECT_STREQ(oneCharString.c_str(), mValue);
        ResetValue();
    }

    // Try to use a default value of length zero => get succeeds
    {
        ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));

        std::string zeroCharString = std::string(0, 'd');

        // Expect that the value matches oneCharString
        int len = property_get(PROPERTY_TEST_KEY, mValue, zeroCharString.c_str());
        EXPECT_EQ(0, len);
        EXPECT_STREQ(zeroCharString.c_str(), mValue);
        ResetValue();
    }

    // Try to use a NULL default value => get returns 0
    {
        ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));

        // Expect a return value of 0
        int len = property_get(PROPERTY_TEST_KEY, mValue, NULL);
        EXPECT_EQ(0, len);
        ResetValue();
    }
}
コード例 #13
0
ファイル: opt_loops.c プロジェクト: davidechiappetta/atalan
Bool OptimizeLoop(Var * proc, InstrBlock * header, InstrBlock * end)
/*
1. Find loop (starting with inner loops)
   - Every jump to label preceding the jump (backjump) forms a label
   - In nested labels, we encounter the backjump first
				<code1>
			l1@
				<code2>
			l2@
				<code3>
				if.. l2@
				<code4>
				if.. l3@
				<code5>

2. Select variable to put to register
   - Most used variable should be used
   - Some variables are already moved to index register (this is considered use too)

3. Compute cost of moving the variable to register

*/
{
	Instr * i, initial, ti, * last_mod;
	Var * top_var, * reg, * top_reg, * orig_result;
	UInt16 r, regi, changed;
	UInt32 var_size;
	Int32 q, top_q, n;
	Bool init, top_init;
	InstrBlock * blk, * last_mod_blk;
	InstrBlock * blk_exit;
	Bool var_modified;
	Bool verbose;
	Rule * rule;
	UInt8 color;

	blk_exit = end->next;

	G_VERBOSE = verbose = Verbose(proc);
	VarResetUse();
	InstrVarUse(header, blk_exit);
	InstrVarLoopDependent(header, end);

	// When processing, we assign var to register
	for(regi = 0; regi < CPU->REG_CNT; regi++) CPU->REG[regi]->var = NULL;

	while(top_var = FindMostUsedVar()) {

//		if (Verbose(proc)) {
//			Print("Most user var: "); PrintVar(top_var); PrintEOL();
//		}

		top_var->read = top_var->write = 0;
		var_size = VarByteSize(top_var);

		//====== Select the best register for the given variable
		//      let %A,%A   => index -3
		//      use of register instead of variable -1
		//      spill +3

		top_q = 0; top_reg = NULL; top_init = false;

		for(regi = 0; regi < CPU->REG_CNT; regi++) {

			reg = CPU->REG[regi];
			if (FlagOn(reg->submode, SUBMODE_IN|SUBMODE_OUT)) continue;		// exclude input/output registers
			if (reg->type->range.max == 1) continue;						// exclude flag registers
			if (var_size != VarByteSize(reg)) continue;						// exclude registers with different byte size
			if (reg->var != NULL) continue;

			if (InstrRule2(INSTR_LET, reg, top_var, NULL)) {

	//			if (StrEqual(reg->name, "x") && StrEqual(top_var->name, "i")) {
	//				Print(" ");
	//			}
				q = UsageQuotient(header, end, top_var, reg, &init);

				if (q < top_q) {
					top_q = q;
					top_reg = reg;
					top_init = init;
				}
			}
		}

		if (top_reg == NULL) continue;

		reg = top_reg;
		if (Verbose(proc)) {
			color = PrintColor(OPTIMIZE_COLOR);
			PrintFmt("*** Loop %d..%d\n", header->seq_no, end->seq_no);
			Print("Var: "); PrintVarVal(top_var); PrintEOL();
			Print("Register: "); PrintVarName(top_reg); PrintEOL();
			PrintFmt("Quotient: %d\n", top_q);
			PrintColor(color);
		}

		//TODO: If there is Let reg = var and var is not top_var, we need to spill store

		//=== Replace the use of registers

//		PrintProc(proc);

		ResetValues();
		initial.op = INSTR_LET; initial.result = top_reg; initial.arg1 = top_var; initial.arg2 = NULL;

		var_modified = false;
		// Generate instruction initializing the register used to replace the variable
		// before the start of the loop.
		// We only do this, if the variable is not initialized inside the loop.

//		if (FlagOn(top_var->flags, VarUninitialized) && !top_init) {
//			top_init = true;
//		}

 		if (top_init) {
			LoopInsertPrologue(proc, header, INSTR_LET, top_reg, top_var, NULL);
			VarSetSrcInstr(top_reg, &initial);
		}
		r = 0;

		last_mod = NULL;

		for(blk = header; blk != blk_exit; blk = blk->next) {
			if (verbose) PrintBlockHeader(blk);
			for(i = blk->first, n=0; i != NULL; i = i->next) {
retry:
				n++;
				if (i->op == INSTR_LINE) {
					if (verbose) { PrintInstrLine(n); EmitInstrInline(i); PrintEOL(); }
					continue;
				}

				// Delete unnecessary assignment
				if (i->op == INSTR_LET) {
					if (!InVar(i->arg1) && !OutVar(i->result) && VarContains(i->result, i->arg1)) {
del:
						if (verbose) { PrintInstrLine(n); EmitInstrInline(i); }
del2:					if (verbose) { PrintDelete(); }
						i = InstrDelete(blk, i);
						if (i == NULL) break;
						goto retry;	//continue;
					}
				}

				// Load the register with variable if necessary
				if (InstrReadsVar(i, top_var)) {
					if (!VarContains(top_reg, top_var)) {
						if (!(i->op == INSTR_LET && i->result == top_reg && i->arg1 == top_var)) {
							InstrInsertRule(blk, i, INSTR_LET, top_reg, top_var, NULL);
						}
					}
				}

				if (i->op == INSTR_LET && (i->result == top_var && i->arg1 == top_reg)) {
					r++;
					goto del;
				}

				if (InstrSpill(i, top_var)) {
					InstrInsertRule(blk, i, INSTR_LET, top_var, top_reg, NULL);
				}

				if (verbose) { PrintInstrLine(n); EmitInstrInline(i); }

				orig_result = i->result;

				memcpy(&ti, i, sizeof(Instr));
				changed = VarTestReplace(&ti.result, top_var, reg);
				r += changed;
				changed += VarTestReplace(&ti.arg1, top_var, reg);
				changed += VarTestReplace(&ti.arg2, top_var, reg);

				// If the instruction used variable, that contains same value as replaced register, use the register instead
				if (ti.arg1 != reg && VarContains(ti.arg1, reg)) {
					changed += VarTestReplace(&ti.result, ti.arg1, reg);
					changed += VarTestReplace(&ti.arg2, ti.arg1, reg);
					changed += VarTestReplace(&ti.arg1, ti.arg1, reg);
				}

				if (changed > 0) {

					if (i->op == INSTR_LET && ti.result == ti.arg1) {
						goto del2;
					}

					rule = InstrRule(&ti);
					if (rule != NULL && (i->rule->cycles >= rule->cycles)) {
						InstrReplaceVar(i, top_var, top_reg);

						if (i->arg1 != reg && VarContains(i->arg1, reg)) {
							VarTestReplace(&i->result, i->arg1, reg);
							VarTestReplace(&i->arg2, i->arg1, reg);
							VarTestReplace(&i->arg1, i->arg1, reg);
						}

						i->rule = rule;
						CheckInstr(i);
						PrintChange(i);
					}

				}

				if (verbose) PrintEOL();
				ResetValue(i->result);
				if (orig_result == top_var) {
//					if (!InstrIsSelfReferencing(i)) {
						VarSetSrcInstr(i->result, &initial);
//					} else {
//						VarSetSrcInstr(i->result, NULL);
//					}
					last_mod = i; last_mod_blk = blk;
				} else {
					VarSetSrcInstr(i->result, i);
				}
			}
		}

		// Value of register is not known at the end of loop, but it is not initialized at the beginning of the loop
		// We must load it before first use.

		if (!top_init && last_mod) {
			InstrInsertRule(last_mod_blk, last_mod->next, INSTR_LET, top_var, top_reg, NULL);
		}

		// If we replaced some destination by the register, store the register to destination
		if (r > 0) {
			// There may be exit label as part of the loop
			// We need to spill after it

			if (!VarIsConst(top_var)) {
				if (blk_exit == NULL || blk_exit->callers != NULL || blk_exit->from != end) {
					blk_exit = InstrBlockAlloc();
					blk_exit->to = end->to;
					blk_exit->next = end->to;
					end->next = blk_exit;
					end->to   = blk_exit;
				}
				InstrInsertRule(blk_exit, blk_exit->first, INSTR_LET, top_var, top_reg, NULL);
			}
//			InstrInsert(blk_exit, blk_exit->first, INSTR_LET, top_var, top_reg, NULL);
		}

		if (FlagOn(top_var->flags, VarLoopDependent)) {
			reg->flags |= VarLoopDependent;
		}

		return true;
	}
	return false;
}
コード例 #14
0
ファイル: opt_loops.c プロジェクト: davidechiappetta/atalan
Int32 UsageQuotient(InstrBlock * header, InstrBlock * end, Var * top_var, Var * reg, Bool * p_init)
/*
Purpose:
	Compute savings achieved by replacing variable top_var by register reg.
	The bigger the value, the more suitable the register is
	0 means no gain, <0 means using the register would lead to less optimal code than if not used
Arguments:
	header	first block of the loop
	end		last block of the loop (it is still part of the loop)
	top_var	variable we want to put in a register
	reg		register to use for the variable
	>p_init	set to true, if we need to init the register with the variable value before the loop
*/{
	Var * prev_var;
	Int32 q;
	UInt16 cycles;
	UInt16 changed;
	InstrBlock * blk, * blk_exit;
	Instr * i, ti;
	UInt32 n;
	Bool first_init, mod_reg;
	UInt16 reg_use;		// number of times, the value in the register has been used since last loaded
	Rule * rule;
	Instr initial;

	blk_exit = end->next;

	// At the beginning, the quotient is 0.
	ResetValues();
	initial.op = INSTR_LET; initial.result = reg; initial.arg1 = top_var; initial.arg2 = NULL;
	VarSetSrcInstr(reg, &initial);

	q = 0;

	// We expect, we will initialize the register with the variable value before entering the loop.
	// This operation is not added to quotient, as it should not affect the speed significantly.

	*p_init = true;
	prev_var = NULL;			// previous variable contained in the register
								// this variable must be loaded, when instruction using the register is encountered
								// (if it is not top_var)
	reg_use = 0;
	first_init = true;

	// Compute usage quotient
	for(blk = header; blk != blk_exit; blk = blk->next) {
		for(i = blk->first, n = 0; i != NULL; i = i->next, n++) {

			if (i->op == INSTR_LINE) continue;

			// Call to subroutine destroys all registers, there will be spill
			if (i->op == INSTR_CALL) { q = 1; goto done; }
			
			// If there is jump except last instruction
			if (IS_INSTR_JUMP(i->op) && (i != blk->last || blk != end)) {
//				*p_init = false;
			}

			mod_reg = VarModifiesVar(i->result, reg);

			if (i->op == INSTR_LET) {
				// If this is let instruction that initializes a variable to value it already contains,
				// we will be able to remove it completely.
				if (!InVar(i->arg1) && !OutVar(i->result) && VarContains(i->result, i->arg1)) {
					if (mod_reg) first_init = false;
					ASSERT(i->rule->cycles > 0);
					q -= i->rule->cycles;
					continue;
				}
			}

			// Instruction uses the register
			if (InstrReadsVar(i, reg)) {
				reg_use++;
				// Instruction uses the register and the register has not been initialized yet.
				// This means, that the register is initialized before the loop and we cannot optimize the loop this way.
				// TODO: Maybe spill to temporary variable is enough?)
				if (first_init) {
					q = 1;
					goto done;
				}
			}

			// Instruction uses top_var and the register does not currently contain the top_var value,
			// we need to load the value to register first.
			if (InstrReadsVar(i, top_var)) {
				if (!VarContains(reg, top_var)) {
					if (!(i->op == INSTR_LET && i->result == reg && i->arg1 == top_var) && LetCycles(reg, top_var, &cycles)) {
						q += cycles;
					}
					reg_use = 0;
					// We may not had to add the load, but we still can not remove this instruction, so do not
					// continue the processing in a normal way, as it would leed to removing the instruction.
					goto next;
				}
			}

			// If we assign the register back to variable, we may remove this instruction
			if (i->op == INSTR_LET && (i->result == top_var && i->arg1 == reg)) {
				q -= i->rule->cycles;
				continue;
			} else {

				// If current instruction uses the register, and it is
				// we need to save the register and load some other.

				if (InstrUsesVar(i, reg) && !VarContains(reg, top_var)) {
					if (prev_var != NULL && LetCycles(reg, top_var, &cycles)) {
						q += cycles;
					}
				}
			}

			// If the instruction stores the result to the variable, we will want to change it to store the result in the top_reg.
			// If the register is currently used for some different purpose, we must spill it.

			if (i->result == top_var && !VarContains(reg, top_var)) {
				if (i->next_use[0] != NULL && LetCycles(top_var, reg, &cycles)) {
					q += cycles;		// TODO: we should use some temporary variable here
				}

				//TODO: In this case, we will need to load the register later, when it is used
				//We should handle the situation.
			// Will it be necessary to spill?
			// We use the variable (array) that is stored to register
			} else if (InstrSpill(i, top_var) && LetCycles(top_var, reg, &cycles)) {
				q += cycles;
			}

			memcpy(&ti, i, sizeof(Instr));
			
			changed = InstrTestReplaceVar(&ti, top_var, reg);

			// If the instruction was changed (it used top_var and it has been replaced to top_reg),
			// test, whether we are able to compile it (some register/adress mode combinations must not be available)

			if (changed > 0) {

				if (ti.op == INSTR_LET && ti.result == ti.arg1) {
					q -= i->rule->cycles;
					continue;
				} 
				rule = InstrRule(&ti);
				if (rule == NULL) {
					if (top_var->mode != INSTR_INT) {
						q = 1;		// do not use this register, as invalid code would get generated
						goto done;
					} else {
						
					}
				} else {
					ASSERT(rule->cycles > 0);
					if (i->rule->cycles >= rule->cycles) {
						q -= i->rule->cycles;			// we remove the current instruction
						q += rule->cycles;              // and add new instruction
					}
				}
			}

			// Instruction modifies the register.
			// We may need to store the value of the register in case it has been modified.

			if (mod_reg) {
				*p_init = false;
				first_init = false;
				reg_use = 0;
			}

next:
			if (i->result != NULL) {
				ResetValue(i->result);
				if (i->result == top_var) {
					if (!InstrIsSelfReferencing(i)) {
						VarSetSrcInstr(reg, &initial);
					} else {
						VarSetSrcInstr(reg, &initial);
//						VarSetSrcInstr(reg, NULL);
					}
				} else {
					VarSetSrcInstr(i->result, i);
				}
			}
		} // instr
	} // blk

	// Value of register is not known at the end of loop, but it is not initialized at the beginning of the loop
	// We must load it before first use.

	if (!*p_init) {
		if (LetCycles(reg, top_var, &cycles)) {
			q += cycles;
		}
	}
done:
	return q;
}
コード例 #15
0
ファイル: dll.cpp プロジェクト: badforlabor/UnityBadConsole
extern "C" int DLL_EXPORT PushCollapsedLog(CLogInfo data)
{
	ResetValue(data);
	CollapsedLogStore.push_back(data);
	return 0;
}
コード例 #16
0
ファイル: dll.cpp プロジェクト: badforlabor/UnityBadConsole
extern "C" int DLL_EXPORT SaveLogStoreInfo(CLogInfo data)
{
	ResetValue(data);
	LogStore.push_back(data);
	return 0;
}