/* * Input: Mem_T structure, unsigned integer * Output: returns the index at which the segment was stored. * Purpose: Adds a segment to memory with numWords words. */ int map_segment(Mem_T memory, unsigned numWords) { int segIndex; int reusedTest = 0; if(Seq_length(memory->reusable_indices) > 0){ segIndex = (int)(intptr_t)Seq_remlo(memory->reusable_indices); reusedTest = 1; } else segIndex = Seq_length(memory->segment_seq); Seq_T segment = Seq_new(numWords); uint32_t initializer = 0; for(unsigned i = 0; i < numWords; i++){ Seq_addhi(segment, (void *)(uintptr_t)initializer); } if(reusedTest) { Seq_put(memory->segment_seq, segIndex, segment); } else { Seq_addhi(memory->segment_seq, segment); } return segIndex; }
/* Creates a segment of desired size, intializes all words to 0 and returns the * identifier. */ ID_SIZE Segment_map(T seg_memory, unsigned size) { //Invariant at work here in the 'if' case WORD_SIZE *seg = malloc(sizeof(WORD_SIZE) * (size + 1)); for (WORD_SIZE i = 0; i < (size + 1); i++) { seg[i] = 0; } assert(seg != NULL); seg[0] = size; ID_SIZE id, i; Seq_T segments = seg_memory->segments; Seq_T unmapped = seg_memory->unmapped_ids; ID_SIZE unmapped_length = Seq_length(unmapped); ID_SIZE segs_length = Seq_length(segments); /* If there aren't any more unmapped id's, we replenish the unmapped id * sequence with MAP_INCREMENT amount. */ if (unmapped_length == 0) { for (i = segs_length; i < segs_length + MAP_INCREMENT; i++) { Seq_addhi(unmapped, (void *)(uintptr_t)i); } } id = (ID_SIZE)(uintptr_t)Seq_remlo(unmapped); if (id >= segs_length) { Seq_addhi(segments, seg); } else { Seq_put(segments, id, seg); } return id; }
void map_segment(int A, int B, int C) { // fprintf(stderr, "in map seg\n"); (void) A; uint32_t c = register_at(C); Seg_array seg_array = initialize_seg_array((int)c); uint32_t id = 0; // fprintf(stderr, "before resize\n"); if (SEG_NUM + 1 >= SEG_LENGTH){ // fprintf(stderr, "in resize\n"); resize_seg_mem(SEG_LENGTH * 2); } // fprintf(stderr, "after resize\n"); if (Seq_length(UNMAP_SEG) == 0){ id = SEG_NUM + 1; SEG_NUM++; } else { id = (uint32_t)(uintptr_t)Seq_remlo(UNMAP_SEG); } assign_to_register(id, B); // fprintf(stderr, "id: %u, seg_num: %d, mem_length: %d\n", id, SEG_NUM, UArray_length(SEG_MEMORY)); SEG_MEMORY[id] = seg_array; //fprintf(stderr, "after seg\n"); }
/* * a new segment is created with number of words equal to what is * in register rC, each word is initialized to zero, and the new ID is * placed in register rB */ extern void segMem_map(segment_data* segments, Seq_T freed_mem, uint32_t* regs, uint32_t* tail, uint32_t* num_segments, int rc_size, int rb_id) { segment_data new_segment = NULL; /* reusage of freed segment identifiers of available */ if (Seq_length(freed_mem) > 0) { int* id = ((int*) Seq_remlo(freed_mem)); new_segment = init_segment(regs, rc_size); segments[*id] = new_segment; regs[rb_id] = *id; free(id); } /* creates a new segment if an old one is not available */ else { uint32_t id = *(tail); new_segment = init_segment(regs, rc_size); assert(new_segment); assert(segments); segments[id] = new_segment; assert(segments[0]); regs[rb_id] = id; *(tail) = id + 1; /* resizing */ if ((*tail) >= (*num_segments)) { segment_data* new_segments = realloc(segments, 2*sizeof(segment_data)*(*num_segments)); if (new_segments != NULL) { segments = new_segments; *(num_segments) = *(num_segments) * 2; } } } }
static void free_address_space(UM_machine machine) { UM_address_space address_space = machine->address_space; /* free the mapped segments sequence */ int length = Seq_length(address_space->mapped_segments); for(int i=0; i<length; i++){ UM_segment segment = Seq_remlo(address_space->mapped_segments); /* if segment with ID == i is mapped, free it */ if(segment != NULL){ free_segment_memory(&segment); } } Seq_free(&address_space->mapped_segments); /* free the reusable IDs sequence */ for(int i=0; i<Seq_length(address_space->reusable_IDs); i++){ UM_segment_ID *seg_ID = Seq_get(address_space->reusable_IDs, i); free(seg_ID); } Seq_free(&(address_space->reusable_IDs)); free(address_space); }
void unblack (Bit2_T bitmap, int cur_x, int cur_y) { int w_pixels = Bit2_width (bitmap); int h_pixels = Bit2_height (bitmap); Seq_T point_queue = Seq_new(w_pixels*h_pixels); assert(point_queue); assert(0 <= cur_x && cur_x < w_pixels); assert(0 <= cur_y && cur_y < h_pixels); if (Bit2_get(bitmap, cur_x, cur_y) != 1) { // if pixel is white assert(point_queue); Seq_free(&point_queue); return; } else { Seq_addhi(point_queue, (void*)makePoint(cur_x,cur_y)); while (Seq_length(point_queue) > 0) { PointPair temp = (PointPair)Seq_remlo(point_queue); assert(temp); int i = temp->i; int j = temp->j; freePoint(temp); if (Bit2_get(bitmap, i, j) == 1) { // if current is black pixel Bit2_put(bitmap, i, j, 0); // set current to white assert(0 <= i && i < w_pixels); assert(0 <= j && j < h_pixels); if (j != 0 && j != h_pixels-1) { // if not a top/bottom pixel if (i+1 < w_pixels && Bit2_get(bitmap, i+1, j) == 1) { // if Seq_addhi(point_queue, (void*)makePoint(i+1,j)); } if (i > 0 && Bit2_get(bitmap, i-1, j) == 1) { Seq_addhi(point_queue, (void*)makePoint(i-1,j)); } } if (i != 0 && i != w_pixels-1) { if (j+1 < h_pixels && Bit2_get(bitmap, i, j+1) == 1) { Seq_addhi(point_queue, (void*)makePoint(i,j+1)); } if (j > 0 && Bit2_get(bitmap, i, j-1) == 1) { Seq_addhi(point_queue, (void*)makePoint(i,j-1)); } } } } assert(point_queue); Seq_free(&point_queue); return; } }
void Um_write_sequence(FILE *output, Seq_T stream) { while(Seq_length(stream) != 0){ union Instruction instruction; instruction.instruction = (Um_instruction)(uintptr_t)Seq_remlo(stream); for(int i = 3; i >= 0; i--){ putc(instruction.bytes[i], output); } } }
/* * halt: Computation stops and deletes all memory that is allocated. */ void halt(Seq_T segMem, Seq_T delMem, uint32_t *arr) { while (Seq_length(segMem) != 0) { struct segment *s = Seq_remlo(segMem); if (s != NULL) { free(s->mem); free(s); } } Seq_free(&segMem); Seq_free(&delMem); free(arr); exit(EXIT_SUCCESS); }
/* stabfend - called at end end of compiling a function */ static void stabfend(Symbol cfunc, int lineno) { int count = Seq_length(locals); for ( ; count > 0; count--) { Symbol p = Seq_remlo(locals); sym_symbol_ty sym = Table_get(uidTable, p); p->x.offset -= tos->x.offset; assert(sym); switch (sym->kind) { case sym_LOCAL_enum: sym->v.sym_LOCAL.offset = p->x.offset; break; case sym_PARAM_enum: sym->v.sym_PARAM.offset = p->x.offset; break; default: assert(0); } } tos = NULL; }
static void *uid2type(int uid) { assert(uid >= 0 && uid < nuids); if (itemmap[uid] == NULL) { Type ty; rcc_type_ty type = (void *)items[uid]; assert(items[uid]); assert(items[uid]->uid == uid); assert(items[uid]->kind == rcc_Type_enum); type = items[uid]->v.rcc_Type.type; assert(type); switch (type->kind) { case rcc_INT_enum: ty = btot(INT, type->size); assert(ty->align == type->align); break; case rcc_UNSIGNED_enum: ty = btot(UNSIGNED, type->size); assert(ty->align == type->align); break; case rcc_FLOAT_enum: ty = btot(FLOAT, type->size); assert(ty->align == type->align); break; case rcc_VOID_enum: ty = voidtype; break; case rcc_POINTER_enum: ty = ptr(uid2type(type->v.rcc_POINTER.type)); break; case rcc_ARRAY_enum: ty = uid2type(type->v.rcc_ARRAY.type); assert(ty->size > 0); ty = array(ty, type->size/ty->size, 0); break; case rcc_CONST_enum: ty = qual(CONST, uid2type(type->v.rcc_CONST.type)); break; case rcc_VOLATILE_enum: ty = qual(VOLATILE, uid2type(type->v.rcc_VOLATILE.type)); break; case rcc_ENUM_enum: { int i, n = Seq_length(type->v.rcc_ENUM.ids); ty = newstruct(ENUM, string(type->v.rcc_ENUM.tag)); ty->type = inttype; ty->size = ty->type->size; ty->align = ty->type->align; ty->u.sym->u.idlist = newarray(n + 1, sizeof *ty->u.sym->u.idlist, PERM); for (i = 0; i < n; i++) { rcc_enum__ty e = Seq_remlo(type->v.rcc_ENUM.ids); Symbol p = install(e->id, &identifiers, GLOBAL, PERM); p->type = ty; p->sclass = ENUM; p->u.value = e->value; ty->u.sym->u.idlist[i] = p; free(e); } ty->u.sym->u.idlist[i] = NULL; Seq_free(&type->v.rcc_ENUM.ids); break; } case rcc_STRUCT_enum: case rcc_UNION_enum: { int i, n; Field *tail; list_ty fields; if (type->kind == rcc_STRUCT_enum) { ty = newstruct(STRUCT, string(type->v.rcc_STRUCT.tag)); fields = type->v.rcc_STRUCT.fields; } else { ty = newstruct(UNION, string(type->v.rcc_UNION.tag)); fields = type->v.rcc_UNION.fields; } itemmap[uid] = ty; /* recursive types */ ty->size = type->size; ty->align = type->align; tail = &ty->u.sym->u.s.flist; n = Seq_length(fields); for (i = 0; i < n; i++) { rcc_field_ty field = Seq_remlo(fields); NEW0(*tail, PERM); (*tail)->name = (char *)field->id; (*tail)->type = uid2type(field->type); (*tail)->offset = field->offset; (*tail)->bitsize = field->bitsize; (*tail)->lsb = field->lsb; if (isconst((*tail)->type)) ty->u.sym->u.s.cfields = 1; if (isvolatile((*tail)->type)) ty->u.sym->u.s.vfields = 1; tail = &(*tail)->link; free(field); } Seq_free(&fields); break; } case rcc_FUNCTION_enum: { int n = Seq_length(type->v.rcc_FUNCTION.formals); if (n > 0) { int i; Type *proto = newarray(n + 1, sizeof *proto, PERM); for (i = 0; i < n; i++) { int *formal = Seq_remlo(type->v.rcc_FUNCTION.formals); proto[i] = uid2type(*formal); free(formal); } proto[i] = NULL; ty = func(uid2type(type->v.rcc_FUNCTION.type), proto, 0); } else ty = func(uid2type(type->v.rcc_FUNCTION.type), NULL, 1); Seq_free(&type->v.rcc_FUNCTION.formals); break; } default: assert(0); } if (itemmap[uid] == NULL) { itemmap[uid] = ty; free(type); free(items[uid]); items[uid] = NULL; } else assert(itemmap[uid] == ty); } return itemmap[uid]; }
static void run(Seq_T values) { int c; /* character from standard input */ waiting: /* * if we are not entering a number, we are here, * awaiting instructions */ c = getchar(); waiting_with_character: switch (c) { case EOF: return; /* push a number */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': push(values, c - '0'); goto entering; /* unary and binary operators */ case '+': BINARY(+); goto waiting; case '-': BINARY(-); goto waiting; case '*': BINARY(*); goto waiting; case '&': BINARY(&); goto waiting; case '|': BINARY(|); goto waiting; case '~' : UNARY(~); goto waiting; case 'c' : UNARY(-); goto waiting; /* "change sign" */ case '/': if (has(values, 2)) { Um_word y = pop(values); Um_word x = pop(values); if (y == 0) { printf("Division by zero\n"); push(values, x); push(values, y); } else if ((int32_t) x < 0) { if ((int32_t) y < 0) { x = -(int32_t)x; y = -(int32_t)y; push(values, x / y); } else { x = -(int32_t)x; Um_word q = x / y; push(values, -(int32_t)q); } } else if ((int32_t) y < 0) { y = -(int32_t) y; Um_word q = x / y; push(values, -(int32_t)q); } else { push(values, x / y); } } goto waiting; case 's': /* swap top two values */ if (has(values, 2)) { Um_word y = pop(values); Um_word x = pop(values); push(values, y); push(values, x); } goto waiting; case 'd': /* duplicate top value */ if (has(values, 1)) { Um_word x = pop(values); push(values, x); push(values, x); } goto waiting; case 'p': /* pop the value stack */ if (has(values, 1)) pop(values); goto waiting; case '\n': /* print the value stack */ for (int i = Seq_length(values); i > 0; i--) printf(">>> %d\n", get(values, i - 1)); goto waiting; case 'z': /* clear (zero out) the value stack by popping all elements */ while (Seq_length(values) > 0) Seq_remlo(values); goto waiting; default: if (!isspace(c)) printf("Unknown character '%c'\n", c); goto waiting; } entering: /* we are in the middle of entering a number */ c = getchar(); switch (c) { /* if we see a digit, add it to number on top of the stack */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': assert(has(values, 1)); Um_word w = pop(values); push(values, 10 * w + c - '0'); goto entering; // if we see anything else, behave as if waiting default: goto waiting_with_character; } }