Пример #1
0
/*  7.8  */
void lookupGenVal(SDocData *data,
                  Segment  *seg)
{
/* The string of the segment can contain subststrings what were specified
 * as 'Attribute value tokens' in SWmlDescriptor. ('.com/','.edu', etc.)
 * Search for these strings and substitute them, breaking the segment into
 * furter segments.
 *---------------------------------------------------------------------------
 */
/* Data Structures */
  PString   str       = seg->m_str;
  UINT16    pos       = 0;
  const WCHAR      *s = STR_DATA(str);
  const SWmlNode *node;


/*  Code  */
  for(; pos<STR_LEN(str); ++pos, ++s) {
      node = FIRST_NODE(data->m_desc->m_generalValues[(*s)&0x7f]);
      for(; node; node=node->m_next) {
      DBG_LOG2( (DBG_WML, node->m_name, "     :") );
          if(STR_LEN(str)>=(STR_LEN(node->m_name)+pos)) {
              const WCHAR *p = STR_DATA(node->m_name);
              const WCHAR *e = p + STR_LEN(node->m_name);
              const WCHAR *t = s;
              for(; p<e && *p==*t; p++,t++)
                  ;
              if(p==e) {
                  if(pos) {
                      seg->m_str = newSubString(str, 0, pos, DOCPOOL);
                      seg        = newSegment(data,0,0,seg);
                  }

                  seg->m_str  = 0;
                  seg->m_code = node->m_code;

                  if(STR_LEN(str)>(STR_LEN(node->m_name)+pos)) {
                      newSegment(data,
                                 newSubString(str,
                                           (UINT16)(pos+STR_LEN(node->m_name)),
                                           (UINT16) STR_LEN(str),
                                              DOCPOOL),
                                 0,
                                 seg);
                  }
                deleteString(str, DOCPOOL);
                return; 
              }
          }
      }
  }
}
Пример #2
0
std::shared_ptr<OsmAnd::RoutePlannerContext::RouteCalculationSegment> OsmAnd::RoutePlannerContext::RoutingSubsectionContext::loadRouteCalculationSegment(
    uint32_t x31, uint32_t y31,
    QMap<uint64_t, std::shared_ptr<const Model::Road> >& processed,
    const std::shared_ptr<RouteCalculationSegment>& original_)
{
    uint64_t id = (static_cast<uint64_t>(x31) << 31) | y31;
    auto itSegment = _roadSegments.constFind(id);
    if(itSegment == _roadSegments.cend())
        return original_;
    this->_access++;

    auto original = original_;
    auto segment = *itSegment;
    while(segment)
    {
        auto road = segment->road;
        auto roadPointId = RoutePlanner::encodeRoutePointId(road, segment->pointIndex);
        auto itOtherRoad = processed.constFind(roadPointId);
        if(itOtherRoad == processed.cend() || (*itOtherRoad)->points.size() < road->points.size())
        {
            processed.insert(roadPointId, road);

            std::shared_ptr<RouteCalculationSegment> newSegment(new RouteCalculationSegment(road, segment->pointIndex));
            newSegment->_next = original;
            original = newSegment;
        }

        segment = segment->next;
    }
    
    return original;
}
Пример #3
0
/*
 * This is equivalent to cc_interupt() in new_dynarec
 *
 */
code_seg_t* Generate_ISR(code_segment_data_t* seg_data)
{
	code_seg_t* 	code_seg 		= newSegment();
	Instruction_t* 	newInstruction;
	Instruction_t* 	ins 			= NULL;

	seg_data->dbgCurrentSegment = code_seg;


	// need to test if interrupts are enabled (Status Register bit 0)
	newInstruction 		= newInstrI(ARM_TST, AL, REG_NOT_USED, REG_STATUS, REG_NOT_USED, 0x01);
	code_seg->Intermcode = ins = newInstruction;

#if USE_INSTRUCTION_COMMENTS
	sprintf(newInstruction->comment, "Generate_ISR() segment 0x%08x\n", (uint32_t)code_seg);
#endif

	ins = insertCall_To_C(code_seg, ins, AL, (size_t)&cc_interrupt, REG_HOST_STM_EABI);

	// Return
	newInstruction 		= newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR);
	ADD_LL_NEXT(newInstruction, ins);

#if USE_TRANSLATE_DEBUG
	Translate_Debug(code_seg);
#endif

	Translate_Registers(code_seg);

	return code_seg;
}
Пример #4
0
void
Buffer::copyIn(const void *data, size_t length)
{
    invariant();

    while (m_writeIt != m_segments.end() && length > 0) {
        size_t todo = (std::min)(length, m_writeIt->writeAvailable());
        memcpy(m_writeIt->writeBuffer().start(), data, todo);
        m_writeIt->produce(todo);
        m_writeAvailable -= todo;
        m_readAvailable += todo;
        data = (unsigned char*)data + todo;
        length -= todo;
        if (m_writeIt->writeAvailable() == 0)
            ++m_writeIt;
        invariant();
    }

    if (length > 0) {
        Segment newSegment(length);
        memcpy(newSegment.writeBuffer().start(), data, length);
        newSegment.produce(length);
        m_segments.push_back(newSegment);
        m_readAvailable += length;
    }

    MORDOR_ASSERT(readAvailable() >= length);
}
///---------------------------------------------------------------------------------
/// fast
///---------------------------------------------------------------------------------
inline const DirectedLineSegment2D DirectedLineSegment2D::operator -( const Vector2& antiTranslation ) const
{
	Vector2 newStart = m_start - antiTranslation;
	Vector2 newEnd = m_end - antiTranslation;
	DirectedLineSegment2D newSegment( newStart, newEnd );
	return newSegment;
}
Пример #6
0
code_seg_t* Generate_BranchUnknown(code_segment_data_t* seg_data)
{
	code_seg_t* 	code_seg 		= newSegment();
	Instruction_t* 	newInstruction;
	Instruction_t* 	ins 			= NULL;

	seg_data->dbgCurrentSegment = code_seg;

	/* Don't think we need this instruction as function branchUnknown() can look
	 * up 'seg_data->dbgCurrentSegment' to:
	 * 1. find/compile the branch target
	 * 2. patch the branch instruction that caused us to end up here.
	 */
	newInstruction 		= newInstr(ARM_MOV, AL, REG_HOST_R0, REG_NOT_USED, REG_HOST_R0);
	code_seg->Intermcode = ins = newInstruction;

#if USE_INSTRUCTION_COMMENTS
	sprintf(newInstruction->comment, "Generate_BranchUnknown() segment 0x%08x\n", (uint32_t)code_seg);
#endif

	ins = insertCall_To_C(code_seg, ins, AL, (uint32_t)&branchUnknown, REG_HOST_STM_R1_3);

	// Now jump to the compiled code
	newInstruction 		= newInstrI(ARM_SUB, AL, REG_HOST_PC, REG_HOST_R0, REG_NOT_USED, 0);
	ADD_LL_NEXT(newInstruction, ins);

#if 0 && USE_TRANSLATE_DEBUG
	Translate_Debug(code_seg);
#endif

	Translate_Registers(code_seg);
	Translate_Literals(code_seg);

	return code_seg;
}
Пример #7
0
static void Test_Translate_Registers_emulate_ldr()
{
    code_seg_t* seg = newSegment();

    seg->Intermcode = newInstr(ARM_MOV, AL, REG_TEMP_SCRATCH0, REG_NOT_USED, 1U);

    Translate_Registers(seg);

    const Instruction_t* const ins_ldr = seg->Intermcode;
    const Instruction_t* const ins_mov = ins_ldr->nextInstruction;

    // Register R2 should be loaded from cache
    assert(ins_ldr->instruction == ARM_LDR);
    assert(ins_ldr->Reg[INS_RD1].regID > REG_HOST);
    assert(ins_ldr->offset == 8U);

    assert(ins_mov->instruction == ARM_MOV);
    assert(ins_mov->Reg[INS_R2].regID == ins_ldr->Reg[INS_RD1].regID);
    assert(ins_mov->Reg[INS_RD1].regID == REG_HOST + 0U);

    assert(ins_mov->nextInstruction == NULL);

    delSegment(seg);

    printf("Test_Translate_Registers_emulate_ldr() passed\n");
}
Пример #8
0
static int putSegmentData(Fingerprint * segmentfp, uint32_t size, void * data) {
	DBService * dbs = getDBService();
	StorageService * sts = getStorageService();

	pthread_mutex_lock(&insertseg_lock);
	Segment * seg = dbs->findSegment(segmentfp);
	if (!seg) {
		seg = newSegment(segmentfp, 0, size);
		dbs->insertSegment(seg);
	} else {
		if (seg->refcnt >= 0) {
			pthread_mutex_unlock(&insertseg_lock);
			return 0;
		} else {
			printf("Re-uploading ");
			printhex(&seg->fp);
			seg->refcnt = 0;
		}
	}
	pthread_mutex_unlock(&insertseg_lock);

	BlockFPStore * bs = sts->getBlockFPStore(seg);
	SegmentStore * ss = sts->getSegmentStore(seg);
	if (!bs || !ss) {
		printf("Cannot get bs %p or ss %p\n", bs, ss);
		free(seg);
		return -1;
	}
	sts->writeSegment(ss, bs, data);
	sts->putSegmentStore(ss);
	sts->putBlockFPStore(bs);
	return 0;
}
JNIEXPORT void JNICALL Java_com_anvato_android_player_hls_HLSNativeConverter_newSegment(JNIEnv *env, jobject obj, jstring filename, jint segmentNo )
{
	LOGD("newSegment() called");

	const char *fname = (*env)->GetStringUTFChars(env, filename, 0);	
	LOGD("%s", fname);
	
	newSegment( fname, segmentNo );

	(*env)->ReleaseStringUTFChars(env, filename, fname);
}
Пример #10
0
void *
pool_AllocNamedSegment (
  pwr_tStatus		*sts,
  pool_sHead		*php,
  pwr_tUInt32		size,
  char			*name
)
{
  int			i;
  pool_sGhead		*gphp;
  pool_sGsegment	*gpsp;
  pool_sSegment		*psp;

  gphp = php->gphp;

  /* Find an empty slot */

  for (i = 0; i < pool_cSegs; i++)
    if (gphp->seg[i].generation == 0 ||
      (gphp->seg[i].type == pool_eSegType_named &&
	strcmp(name, gphp->seg[i].name) == 0))
      break;

  if (i >= pool_cSegs)
    pwr_Return(NULL, sts, POOL__NOSLOT);

  gpsp = &gphp->seg[i];
  psp = &php->seg[i];

  /* Allocate the section */

  if (gpsp->generation == 0) {
    psp = newSegment(sts, php, entryUnits(size));
    if (psp == NULL) return NULL;
    memset(psp->base, 0, size);
    gpsp->type = pool_eSegType_named;
    strncpy(gpsp->name, name, sizeof(gpsp->name) - 1);
    gpsp->name[sizeof(gpsp->name) - 1] = '\0';
  } else {
    psp = ensureMapped(sts, php, psp);
    if (psp == NULL) return NULL;
  }

  return psp->base;
}
Пример #11
0
public void prepareSegment(World* world, Vec4i pos)
{

    Vec4i global=pos-world->scroll;

    for(int i=0;i<3;i++)
        if(global[i]<0 || global[i]>=VIEW_RANGE)
            return;

    Segment* segment=world->segment[global[2]][global[1]][global[0]];

    if(segment==NULL)
    {
        segment=newSegment();
        world->segment[global[2]][global[1]][global[0]]=segment;
        generateSegment(world,segment,pos);
    }
}
Пример #12
0
static void Test_Translate_Registers_emulate_temp()
{
    code_seg_t* seg = newSegment();

    seg->Intermcode = newInstrI(ARM_MOV, AL, REG_TEMP_SCRATCH0, REG_NOT_USED, REG_NOT_USED, 0);

    Translate_Registers(seg);

    const Instruction_t* const ins_mov = seg->Intermcode;

    // Register R2 should be loaded from cache
    assert(ins_mov->instruction == ARM_MOV);
    assert(ins_mov->Reg[INS_RD1].regID == REG_HOST_R0);

    assert(ins_mov->nextInstruction == NULL);

    delSegment(seg);

    printf("Test_Translate_Registers_emulate_temp() passed\n");
}
Пример #13
0
void
Buffer::adopt(void *buffer, size_t length)
{
    invariant();
    Segment newSegment(buffer, length);
    if (readAvailable() == 0) {
        // put the new buffer at the front if possible to avoid
        // fragmentation
        m_segments.push_front(newSegment);
        m_writeIt = m_segments.begin();
    } else {
        m_segments.push_back(newSegment);
        if (m_writeAvailable == 0) {
            m_writeIt = m_segments.end();
            --m_writeIt;
        }
    }
    m_writeAvailable += length;
    invariant();
}
Пример #14
0
code_seg_t* Generate_MIPS_Trap(code_segment_data_t* seg_data)
{
	code_seg_t* 	code_seg 		= newSegment();
	Instruction_t* 	newInstruction;
	Instruction_t* 	ins 			= NULL;

	seg_data->dbgCurrentSegment = code_seg;

	// Return
	newInstruction 		= newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR);
	code_seg->Intermcode = ins = newInstruction;

#if USE_TRANSLATE_DEBUG
	Translate_Debug(code_seg);
#endif

	Translate_Registers(code_seg);

	return code_seg;
}
Пример #15
0
void
Clipboard::copyFrom(const Clipboard *c)
{
    if (c == this) return;
    clear();

    for (Clipboard::const_iterator i = c->begin(); i != c->end(); ++i) {
        newSegment(*i);
    }

    m_partial = c->m_partial;

    m_timeSigSelection = c->m_timeSigSelection;
    m_haveTimeSigSelection = c->m_haveTimeSigSelection;

    m_tempoSelection = c->m_tempoSelection;
    m_haveTempoSelection = c->m_haveTempoSelection;
    
    m_nominalStart = c->m_nominalStart;
    m_nominalEnd = c->m_nominalEnd;
}
Пример #16
0
void
Buffer::reserve(size_t length)
{
    if (writeAvailable() < length) {
        // over-reserve to avoid fragmentation
        Segment newSegment(length * 2 - writeAvailable());
        if (readAvailable() == 0) {
            // put the new buffer at the front if possible to avoid
            // fragmentation
            m_segments.push_front(newSegment);
            m_writeIt = m_segments.begin();
        } else {
            m_segments.push_back(newSegment);
            if (m_writeAvailable == 0) {
                m_writeIt = m_segments.end();
                --m_writeIt;
            }
        }
        m_writeAvailable += newSegment.length();
        invariant();
    }
}
Пример #17
0
code_seg_t* Generate_CodeStop(code_segment_data_t* seg_data)
{
	code_seg_t* 	code_seg 		= newSegment();
	Instruction_t* 	newInstruction;
	Instruction_t* 	ins 			= NULL;

	seg_data->dbgCurrentSegment = code_seg;

	newInstruction 		= newInstrPOP(AL, REG_HOST_STM_EABI2 );
	code_seg->Intermcode = ins = newInstruction;

	newInstruction 		= newInstrI(ARM_MOV, AL, REG_HOST_R0, REG_NOT_USED, REG_NOT_USED, 0);
	ADD_LL_NEXT(newInstruction, ins);

	// Return
	newInstruction 		= newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR);
	ADD_LL_NEXT(newInstruction, ins);

	Translate_Registers(code_seg);

	return code_seg;
}
Пример #18
0
static void Test_Translate_Registers_emulate_str()
{
    code_seg_t* seg = newSegment();

    seg->Intermcode = newInstrI(ARM_MOV, AL, 1U, REG_NOT_USED, REG_NOT_USED, 0);

    Translate_Registers(seg);

    const Instruction_t* const ins_mov = seg->Intermcode;
    const Instruction_t* const ins_str = ins_mov->nextInstruction;

    // Register R2 should be loaded from cache
    assert(ins_mov->instruction == ARM_MOV);
    assert(ins_mov->Reg[INS_RD1].regID > REG_HOST);

    assert(ins_str->instruction == ARM_STR);
    assert(ins_str->Reg[INS_R1].regID == ins_mov->Reg[INS_RD1].regID);
    assert(ins_str->offset ==  8U);

    delSegment(seg);

    printf("Test_Translate_Registers_emulate_str() passed\n");
}
Пример #19
0
static void Test_Translate_Registers_emulate_full()
{
    code_seg_t* seg = newSegment();

    seg->Intermcode = newInstr(ARM_MOV, AL, REG_TEMP_SCRATCH0, REG_NOT_USED, 1U);

    Instruction_t* ins = seg->Intermcode;
    uint32_t r = 1U;

    for (r = 1U; r < 32U; r++)
    {
        ins->nextInstruction = newInstrI(ARM_MOV, AL, r, REG_NOT_USED, REG_NOT_USED, r);
        ins = ins->nextInstruction;
    }

    ins->nextInstruction = newInstrB(AL, *((uint32_t*)(MMAP_FP_BASE + FUNC_GEN_STOP)), 1);


    Translate_Registers(seg);
    Translate_Write(seg);


    *((volatile int32_t*)MMAP_FP_BASE + REG_COUNT) = -1000;
    *((uintptr_t*)(MMAP_FP_BASE + RECOMPILED_CODE_START)) = (uintptr_t)seg->ARMEntryPoint;

    delSegment(seg);

    run();

    for (r = 1U; r < 32U; r++)
    {
        printf("r%u = %u\n", r, reg[r]);
        assert(reg[r] == r);
    }

    printf("Test_Translate_Registers_emulate_full() passed\n");
}
Пример #20
0
/*
 * Function Called to Begin Running Dynamic compiled code.
 */
code_seg_t* Generate_CodeStart(code_segment_data_t* seg_data)
{
	code_seg_t* 	code_seg 		= newSegment();
	Instruction_t* 	newInstruction;
	Instruction_t* 	ins 			= NULL;

	seg_data->dbgCurrentSegment = code_seg;

	code_seg->Type = SEG_START;

	newInstruction 		= newInstrPUSH(AL, REG_HOST_STM_EABI2 );
	code_seg->Intermcode = ins = newInstruction;

	regID_t base;
	int32_t offset;

#if defined(TEST_BRANCHING_FORWARD)
	newInstruction 		= newInstrI(ARM_MOV, AL, REG_HOST_R0, REG_NOT_USED, REG_NOT_USED, 0);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_B, AL, REG_NOT_USED, REG_NOT_USED, REG_NOT_USED, 3);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x1);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x2);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x4);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x8);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x10);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x20);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x40);
	ADD_LL_NEXT(newInstruction, ins);

	// return back to debugger
	newInstruction 		= newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR);
	ADD_LL_NEXT(newInstruction, ins);

#elif defined(TEST_BRANCHING_BACKWARD)

// Jump forwards to the Landing Pad
	newInstruction 		= newInstrI(ARM_MOV, AL, REG_HOST_R0, REG_NOT_USED, REG_NOT_USED, 0);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_B, AL, REG_NOT_USED, REG_NOT_USED, REG_NOT_USED, 10);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x1);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x2);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x4);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x8);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x10);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x20);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x40);
	ADD_LL_NEXT(newInstruction, ins);

// return back to debugger
	newInstruction 		= newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR);
	ADD_LL_NEXT(newInstruction, ins);

// Landing pad
	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0);
	ADD_LL_NEXT(newInstruction, ins);

// Now jump backwards
	newInstruction 		= newInstrI(ARM_B, AL, REG_NOT_USED, REG_NOT_USED, REG_NOT_USED, -10);
	ADD_LL_NEXT(newInstruction, ins);

#elif defined(TEST_BRANCH_TO_C)

	newInstruction 		= newInstrI(ARM_MOV, AL, REG_HOST_R0, REG_NOT_USED, REG_NOT_USED, 0);
	ADD_LL_NEXT(newInstruction, ins);

	addLiteral(code_seg, &base, &offset,(uint32_t)&test_callCode);
	assert(base == REG_HOST_PC);

	newInstruction 		= newInstrI(ARM_LDR_LIT, AL, REG_HOST_R1, REG_NOT_USED, base, offset);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstr(ARM_MOV, AL, REG_HOST_LR, REG_NOT_USED, REG_HOST_PC);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_R1);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstrPOP(AL, REG_HOST_STM_EABI2 );
	ADD_LL_NEXT(newInstruction, ins);

	// Return back to Debugger
	newInstruction 		= newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR);
	ADD_LL_NEXT(newInstruction, ins);

#elif defined(TEST_LITERAL)	// Test Literal loading

	addLiteral(code_seg, &base, &offset,(uint32_t)MMAP_FP_BASE);
	assert(base == REG_HOST_PC);

	newInstruction 		= newInstrI(ARM_LDR_LIT, AL, REG_HOST_R0, REG_NOT_USED, base, offset);
	ADD_LL_NEXT(newInstruction, ins);

	// return back to debugger
	newInstruction 		= newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR);
	ADD_LL_NEXT(newInstruction, ins);

#elif defined(TEST_ROR)

	newInstruction 		= newInstrI(ARM_MOV, AL, REG_HOST_R0, REG_NOT_USED, REG_NOT_USED, 0x00138000);
	ADD_LL_NEXT(newInstruction, ins);

	newInstruction 		= newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR);
	ADD_LL_NEXT(newInstruction, ins);

#else
	addLiteral(code_seg, &base, &offset,(uint32_t)MMAP_FP_BASE);
	assert(base == REG_HOST_PC);

	// setup the HOST_FP
	newInstruction 		= newInstrI(ARM_LDR_LIT, AL, REG_EMU_FP, REG_NOT_USED, base, offset);
	ADD_LL_NEXT(newInstruction, ins);

	// start executing recompiled code
	newInstruction 		= newInstrI(ARM_LDR, AL, REG_HOST_PC, REG_NOT_USED, REG_EMU_FP, RECOMPILED_CODE_START);
	ADD_LL_NEXT(newInstruction, ins);
#endif

	Translate_Registers(code_seg);
	Translate_Literals(code_seg);

	return code_seg;
}
Пример #21
0
pool_sHead *
pool_Create (
  pwr_tStatus		*sts,
  pool_sHead		*php,
  char			*name,
  size_t		initsize,
  size_t		extendsize
)
{
  pwr_tStatus		lsts;
  pwr_tBoolean		created;
  pwr_tUInt32		seg;
  pool_sSegment		*psp;
  pool_sGsegment	*gpsp;
  pool_sGhead		*gphp;
  pool_sHead		*lphp = NULL;
  sect_sHead		*shp;
  size_t		alloc_size = 0;
  size_t		alloced_size = 0;

  if (php == NULL) php = lphp = (pool_sHead *) calloc(1, sizeof(*lphp));
  if (php == NULL)
    pwr_Return(NULL, sts, POOL__INSVIRMEM);

  if (php->created == cEntryMark)
    pwr_Return(NULL, sts, POOL__ALLRMAPPED);

  do {
    shp = sect_Alloc(&lsts, &created, &php->sect, sizeof(*gphp), name);
    if (shp == NULL) break;

    gphp = (pool_sGhead *) shp->base;

    if (created) {
      strncpy(gphp->name, name, sizeof(gphp->name) - 1);
      gphp->name[sizeof(gphp->name) - 1] = '\0';

      gphp->initsize = entryUnits(initsize);
      gphp->extendsize = entryUnits(extendsize);
      gphp->generation = 1;
    }
      
    php->gphp = gphp;

    for (
      seg = 0, gpsp = &gphp->seg[0], psp = &php->seg[0];
      seg < pool_cSegs;
      seg++, gpsp++, psp++
    ) {
      gpsp->seg	= seg;
      psp->seg	= seg;
      psp->gpsp	= gpsp;

      if (gpsp->generation > 0) {
	psp = mapSegment(sts, php, psp);
	if (psp == NULL) break;      
      }
    }
    
    /* Allocate initial segment */

    if (created) {
      if (gphp->initsize != 0) {
	alloced_size = 0;
	while (alloced_size < initsize) {
	  alloc_size = MAX(MIN(initsize - alloced_size, pool_cMaxSize), MIN(extendsize,  pool_cMaxSize));
	  psp = newSegment(&lsts, php, entryUnits(alloc_size));
	  if (psp == NULL) break;
	  alloced_size += alloc_size;
	}
      }
      if (psp == NULL) break;
      gphp->created = cEntryMark;
    }

    php->created = cEntryMark;

    pwr_Return(php, sts, 1);

  } while (0);

  /* Something is wrong, cleanup!  */

  if (lphp != NULL) free(lphp);

  pwr_Return(NULL, sts, lsts);
}
Пример #22
0
/*
 * Description: Function to malloc a newSegment and zero initialize it.
 *
 * Parameters:	none
 *
 * Returns:		code_seg_t*
 */
code_seg_t* newSegment()
{
	code_seg_t* newSeg = malloc(sizeof(code_seg_t));
	memset(newSeg, 0,sizeof(code_seg_t));

#if SHOW_PRINT_SEGMENT_DELETE == 2
	{
#elif SHOW_PRINT_SEGMENT_DELETE == 1
	if (showPrintSegmentDelete)
	{
#else
	if (0)
	{
#endif
		printf("new Segment 0x%08x\n", (uint32_t)newSeg);
	}

	return newSeg;
}

/*
 * Description: Function to free a segment and its associated data.
 *
 * 				Function will also invalidate the branches of code segments that branch to this one
 * 				and delete segments that 'continue' execution to this one.
 *
 * Parameters:	none
 *
 * Returns:		code_seg_t*
 */
uint32_t delSegment(code_seg_t* codeSegment)
{
	uint32_t ret = 0;

#if SHOW_PRINT_SEGMENT_DELETE == 2
	{
#elif SHOW_PRINT_SEGMENT_DELETE == 1
	if (showPrintSegmentDelete)
	{
#else
	if (0)
	{
#endif
	printf("deleting Segment 0x%08x for mips code at 0x%08x\n", (uint32_t)codeSegment, (uint32_t)codeSegment->MIPScode);
	}

	freeIntermediateInstructions(codeSegment);	// free memory used for Intermediate Instructions
	freeLiterals(codeSegment);					// free memory used by literals

	// Clean up all segments that branch or continue to this segment
	if (codeSegment->callers != NULL)
	{
		caller_t* caller = codeSegment->callers;

		// loop through all the callers
		while (caller != NULL)
		{
			if (caller->codeSeg != NULL)
			{
				// if the found caller branches to this segment then remove the reference
				if (caller->codeSeg->pBranchNext == codeSegment)
				{
					caller->codeSeg->pBranchNext = NULL;
				}
				// if the found caller continues to this segment then it MUST also be deleted
				else if (caller->codeSeg->pContinueNext == codeSegment)
				{
					delSegment(caller->codeSeg);
				}
			}
			caller = caller->next;
		}

		// Invalidate any segments that branch to this segment and free the caller_t objects
		freeCallers(codeSegment);
	}

	// update the codeSegment mapping
	setMemState((size_t)codeSegment->MIPScode, codeSegment->MIPScodeLen, NULL);

	free(codeSegment);

	return ret;
}

/*
 * Description: Function to Compile the code starting at 'address'.
 *
 * 				This function will scan the code until an unconditional Jump is found. Referred to as a super block
 *
 * 				It may detect multiple segments in which case these will all 'continue' execution into the next segment.
 *
 * 				It also detects internal loops and separates these into their own segment, for better register optimization.
 *
 *
 * Parameters:	const uint32_t* const address				The address to start compiling from.
 *
 * Returns:		code_seg_t*	The first generated code Segment.
 */
code_seg_t* CompileCodeAt(const uint32_t const address[])
{
	uint32_t 		x;
	Instruction_e 	op;
	uint32_t 		uiMIPScodeLen = 0U;
	code_seg_t* 	newSeg;
	code_seg_t* 	prevSeg = NULL;

	// Find the shortest length of contiguous blocks (super block) of MIPS code at 'address'
	// Contiguous blocks should end with an OPS_JUMP && !OPS_LINK
	for (;;) // (index + uiMIPScodeLen < upperAddress/sizeof(code_seg_t*))
	{
		op = ops_type(address[uiMIPScodeLen]);

		if (DR_INVALID == op)
		{
			uiMIPScodeLen = 0U;
			break;
		}

		uiMIPScodeLen++;

		if ((op & OPS_JUMP) == OPS_JUMP
				&& (op & OPS_LINK) != OPS_LINK)	//unconditional jump or function return
		{
			break;
		}
	}

#if	SHOW_COMPILEAT_STEPS
	printf("CompiltCodeAt(0x%x) - found %u potential instructions\n", address, uiMIPScodeLen);
#endif

	//Now expire the segments within the super block and remove the segments
	for (x = 0U; x < uiMIPScodeLen; x++)
	{
		code_seg_t* toDelete;
		toDelete = getSegmentAt((size_t)(address + x));
		if (toDelete)
		{
			setMemState((size_t)toDelete->MIPScode, toDelete->MIPScodeLen, NULL);
			delSegment(toDelete);

			//we can skip next few words as we have already cleared them.
			x += toDelete->MIPScodeLen - 1U;
		}
	}

	uint32_t segmentStartIndex = 0U;

	// Create new segments
	for (x = 0U; x < uiMIPScodeLen; x++)
	{
		op = ops_type(address[x]);

		if ((op & OPS_JUMP) == OPS_JUMP)
		{
			//uint32_t uiAddress = ops_JumpAddress(&address[x]);

			newSeg = newSegment();
			newSeg->MIPScode = (uint32_t*)(address + segmentStartIndex);
			newSeg->MIPScodeLen = x - segmentStartIndex + 1U;

#if	SHOW_COMPILEAT_STEPS
				printf("CompiltCodeAt(0x%x) - new external jump segment 0x%x at address 0x%x\n", address + x * 4U, newSeg, newSeg->MIPScode);
#endif
			if (op == MIPS_JR) //only JR can set PC to the Link Register (or other register!)
			{
				newSeg->MIPSReturnRegister = (*address>>21U)&0x1fU;
			}

			if (prevSeg)
			{
				prevSeg->pContinueNext = newSeg;
				addToCallers(prevSeg, newSeg);
			}
			prevSeg = newSeg;

			if (!segmentStartIndex)
			{
				newSeg->Type = SEG_START;
			}
			else
			{
				newSeg->Type = SEG_END;
			}

			setMemState((size_t)(address + segmentStartIndex), newSeg->MIPScodeLen, newSeg);

			segmentStartIndex = x + 1U;

			// we should have got to the end of the super block
			if (!(op & OPS_LINK))
			{
				break;
			}
		}
		else if((op & OPS_BRANCH) == OPS_BRANCH)	//MIPS does not have an unconditional branch
		{
			int32_t offset =  ops_BranchOffset(&address[x]);

			//Is this an internal branch - need to create two segments
			// if use x<= y + offset then may throw SIGSEGV if offset is -1!
			if (offset < 0 && x + offset >= segmentStartIndex )
			{
				newSeg = newSegment();
				newSeg->MIPScode = (uint32_t*)(address + segmentStartIndex);
				newSeg->MIPScodeLen = x + offset - segmentStartIndex + 1U;

#if	SHOW_COMPILEAT_STEPS
				printf("CompiltCodeAt(0x%x) - new internal branching, pre-loop segment 0x%x to address 0x%x\n", address, newSeg, newSeg->MIPScode);
#endif

				if (prevSeg != NULL)
				{
					prevSeg->pContinueNext = newSeg;
					addToCallers(prevSeg, newSeg);
				}
				prevSeg = newSeg;

				if (segmentStartIndex == 0U)
				{
					newSeg->Type = SEG_START;
				}
				else
				{
					newSeg->Type = SEG_SANDWICH;
				}

				setMemState((size_t)(address + segmentStartIndex), newSeg->MIPScodeLen, newSeg);
				segmentStartIndex = x + 1U;

				newSeg = newSegment();
				newSeg->MIPScode = (uint32_t*)(address + segmentStartIndex + offset);
				newSeg->MIPScodeLen = -offset;
				newSeg->Type = SEG_SANDWICH;

#if	SHOW_COMPILEAT_STEPS
				printf("CompiltCodeAt(0x%x) - new internal branching self-looping segment 0x%x to address 0x%x\n", address, newSeg, newSeg->MIPScode);
#endif
				prevSeg->pContinueNext = newSeg;
				addToCallers(prevSeg, newSeg);
				prevSeg = newSeg;

				setMemState((size_t)(address + segmentStartIndex + offset), newSeg->MIPScodeLen, newSeg);
				segmentStartIndex = x + 1U;
			}
			else // if we are branching external to the block?
			{
				newSeg = newSegment();
				newSeg->MIPScode = (uint32_t*)(address + segmentStartIndex);
				newSeg->MIPScodeLen = x - segmentStartIndex + 1U;
#if	SHOW_COMPILEAT_STEPS
				printf("CompiltCodeAt(0x%x) - new external branching segment 0x%x to address 0x%x\n", address, newSeg, newSeg->MIPScode);
#endif
				setMemState((size_t)(address + segmentStartIndex), newSeg->MIPScodeLen, newSeg);

				//
				if (prevSeg != NULL)
				{
					prevSeg->pContinueNext = newSeg;
					addToCallers(prevSeg, newSeg);
				}

#if 1
				code_seg_t* externalSegment = getSegmentAt((uint32_t)(address + segmentStartIndex + offset));
				if (externalSegment != NULL)
				{

#if	SHOW_COMPILEAT_STEPS
					printf("CompiltCodeAt(0x%x) - segment 0x%x branches to segment 0x%x to address \n", address, newSeg, externalSegment, externalSegment->MIPScode);
#endif
					newSeg->pBranchNext = externalSegment;
					// addToCallers() will be done when compiling code within C_Interface.c:branchUnknown()
				}
#endif
				prevSeg = newSeg;

				if (segmentStartIndex == 0U)
				{
					newSeg->Type = SEG_START;
				}
				else
				{
					newSeg->Type = SEG_SANDWICH;
				}

				segmentStartIndex = x + 1U;
			}
		}
	} // for (x = 0; x < uiMIPScodeLen; x++)
Пример #23
0
pwr_tBoolean
pool_AllocLookasideSegment (
  pwr_tStatus		*sts,
  pool_sHead		*php,
  pwr_tUInt32		count,
  pwr_tUInt32		size
)
{
  int			i;
  pool_sGhead		*gphp;
  pool_sGsegment	*gpsp;
  pool_sSegment		*psp;
  pool_tRef		offs;
  pwr_tUInt32		esize;
  pool_sEntry		*ep;

  gphp = php->gphp;

  if (gphp->la_idx >= pool_cLists)
    pwr_Return(NO, sts, POOL__NOLIST);

  /* Find an empty slot */

  for (i = 0; i < pool_cSegs; i++)
    if (gphp->seg[i].generation == 0 ||
      (gphp->seg[i].type == pool_eSegType_lookaside &&
	gphp->seg[i].la_size == size))
      break;

  if (i >=  pool_cSegs)
    pwr_Return(NO, sts, POOL__NOSLOT);

  gpsp = &gphp->seg[i];
  psp = &php->seg[i];

  /* Allocate the section */

  if (gpsp->generation == 0) {
    esize = entryUnits(size + sizeof(pool_sEntry));   /* Add space for entry header.  */
    psp = newSegment(sts, php, count * esize);
    if (psp == NULL) return NO;
    gpsp = psp->gpsp;
    gpsp->type = pool_eSegType_lookaside;
    gpsp->la_size = size;
    gpsp->la_idx = gphp->la_idx;
    gpsp->fragcnt = count;
    gphp->la[gphp->la_idx].seg = i;
    gphp->la[gphp->la_idx].size = size;
    gphp->la_idx++;
    for (i = 0, offs = 0; i < count - 1; i++) {
      ep = (pool_sEntry *)((char *)psp->base + offs * pool_cDataSize);
      ep->size = esize;
      offs += esize;
      ep->next = offs;
    }
    ep->next = pool_cNOffset;
    gpsp->freeroot.next = 0;    
    gpsp->freeroot.size = esize;
    gphp->la[gphp->la_idx].next = 0;
  } else {
    psp = ensureMapped(sts, php, psp);
    if (psp == NULL) return NO;
  }

  return YES;
}
Пример #24
0
void *
pool_Alloc (
  pwr_tStatus		*sts,
  pool_sHead		*php,
  pwr_tUInt32		size
)
{
  pwr_tStatus		lsts = 1;
  pool_sGhead		*gphp;
  pool_sGsegment	*gpsp;
  pool_sSegment		*psp;
  pool_sEntry		*ep;
  pool_sEntry		*prevp;
  pool_sEntry		*tmpp;
  pwr_tUInt32		esize;	/* True size ( incl header) in pool_sData units */
  pwr_tUInt32		tmpsize;
  pwr_tBoolean		found;
  pool_uRefBits		pr;
  pwr_tUInt32		i = 0;

#if 0
  pwr_SetStatus(sts, 1);
#endif

  gphp = php->gphp;

  if (size == gphp->la[0].size) {
    if (gphp->la[0].next != pool_cNOffset)
      return allocLookaside(sts, php, &gphp->la[0]);
  } else if (size == gphp->la[1].size) {
    if (gphp->la[1].next != pool_cNOffset)
      return allocLookaside(sts, php, &gphp->la[1]);
  } else if (size == gphp->la[2].size) {
    if (gphp->la[2].next != pool_cNOffset)
      return allocLookaside(sts, php, &gphp->la[2]);
  } else if (size == gphp->la[3].size) {
    if (gphp->la[3].next != pool_cNOffset)
      return allocLookaside(sts, php, &gphp->la[3]);
  }

  esize = entryUnits(size + sizeof(pool_sEntry));	 /* Add space for header */

  /* Find a segment where there is room.  */

  found = FALSE;
  for (
    i = 0, gpsp = &gphp->seg[0], psp = &php->seg[0];
    i < pool_cSegs;
    i++, gpsp++, psp++
  ) {
    if (gpsp->generation == 0)
      break;

    if (gpsp->type != pool_eSegType_dynamic)
      continue;

    if (gpsp->fragmax >= esize) {
      found = TRUE;
      break;
    }
  }

  /* Allocate a new segment if noone fits,
     otherwise make sure the existing segment is mapped.  */

  if (!found)
    psp = newSegment(&lsts, php, MAX(gphp->extendsize, esize));
  else
    psp = ensureMapped(&lsts, php, psp);

  if (psp == NULL)
    errh_ReturnOrBugcheck(NULL, sts, lsts, "");

  /* Walk through the free list of the chosen segment.
     The segment is pointed out by psp/gpsp!  */

  ep = NULL;
  prevp = &gpsp->freeroot;
  while (prevp->next != pool_cNOffset) {
    tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize);
    if (tmpp->size >= esize) {	/* Found */
      ep = tmpp;
      break;
    } /* If the entry is larger or equal to the requested */

    prevp = tmpp;			/* Try next */
  } /* While more entries in free list */

  /* Now ep points to the chosen free list entry. Remove this entry
     from the list, or split it if it is larger than requested.
     We need to update the fragmentation information, too.

     If we come here without a selection
     there is an internal consistency problem.  */

  if (ep == NULL)
    errh_Bugcheck(POOL__BUGCHECK, "");

  tmpsize = ep->size;

  if (ep->size == esize || 
      (ep->size - esize > 0 && 
       (ep->size - esize) * pool_cDataSize < sizeof(pool_sEntry))) {	/* Entry fits exactly */
    prevp->next = ep->next;
    --gpsp->fragcnt;
  }
  else {	/* Entry is to big, split it */
    prevp->next = prevp->next + esize;
    tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize);
    tmpp->next = ep->next;
    tmpp->size = ep->size - esize;
    ep->size = esize;
  }
  memset( entryPAdd(ep, sizeof(pool_sEntry)), 0, esize*pool_cDataSize - sizeof(pool_sEntry));
  ep->next = cEntryMark;

  gpsp->alloccnt++;
  gpsp->fragsize -= esize;

  /* Keep track of the maximum fragment size and count */

  if (tmpsize == gpsp->fragmax) {
    if ((--gpsp->fragmaxcnt) == 0) {	/* In this special case we need to */
				    /* rebuild the fragmax&cnt info */
      gpsp->fragmax = 0;
      gpsp->fragmaxcnt = 1;
      prevp = &gpsp->freeroot;
      while (prevp->next != pool_cNOffset) {
	tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize);
	if (tmpp->size >= gpsp->fragmax) {
	  if (tmpp->size == gpsp->fragmax) gpsp->fragmaxcnt++;
	  else {
	    gpsp->fragmaxcnt = 1;
	    gpsp->fragmax = tmpp->size;
	  } /* new fragmax entry found */
	} /* new or equal to fragmax found */
	prevp = tmpp;			/* next entry */
      } /* While more entries in free list */
    } /* If no more fragmax entries left */
  } /* If this was a fragmax entry */

  pr.m = pool_cNRef;
  pr.b.seg = psp->seg;
  pr.b.offs = (pool_tOffset)((char *)ep + sizeof(pool_sEntry) - (char *)psp->base);
  ep->next = pr.m;

  return (void *)(entryPAdd(ep, sizeof(pool_sEntry)));
}