/* 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; } } } } }
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; }
/* * 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; }
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; }
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; }
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"); }
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); }
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; }
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); } }
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"); }
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(); }
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; }
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; }
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(); } }
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; }
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"); }
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"); }
/* * 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; }
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); }
/* * 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++)
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; }
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))); }