// Creates an unboxed array of dimensions width * height (= size) // Note that height is num rows, width is num cols // returns a pointer to the unboxed array T UArray2_new(int height, int width, int size) { T uarray2 = malloc(sizeof(*uarray2)); //RAISE(Mem_Failed); uarray2 -> array = UArray_new(height, (sizeof(UArray_T*))); int i; for(i = 0; i < height; i++) { //UArray_T uarray = malloc(size); // necessary? // UArray_T uarray = UArray_new(width, size); UArray_T* row = UArray_at(uarray2 -> array, i); *row = UArray_new(width, size); int j; for(j = 0; j < width; j++) { int* elemp = UArray_at(*row, j); *elemp = 0; } } uarray2 -> height = height; uarray2 -> width = width; uarray2 -> size = size; return uarray2; }
static void copy_segment_to_m0(UM_machine machine, UM_segment_ID segment_ID) { Seq_T mapped_segments = machine->address_space->mapped_segments; UM_segment temp = Seq_get(mapped_segments, segment_ID); int temp_length = UArray_length(temp->words); UM_segment duplicate = get_new_segment_of_size(temp_length); /* copy words into the new segment */ for(int i=0; i<temp_length; i++){ UM_word *word_i_p = UArray_at(temp->words, i); UM_word *duplicate_word_i_p = UArray_at(duplicate->words, i); *duplicate_word_i_p = *word_i_p; } duplicate->ID = 0; /* free the old program segment */ UM_segment program = Seq_get(mapped_segments, 0); free_segment_memory(&program); /* put the duplicate segment in the place of the old program segment */ Seq_put(mapped_segments, 0, duplicate); /* update num_instructions */ machine->num_instructions = temp_length; }
void verifyMapped(Seq_T memorySegments, Seq_T unmappedSegments) { // Verifies that the available unmapped segments is updated upon mapping for(int i = 0; i < Seq_length(unmappedSegments); i++){ UM_Word index = *(UM_Word*)Seq_get(unmappedSegments, i); if((UArray_T)Seq_get(memorySegments, index) != NULL){ fprintf(stderr, "Unmapped segments not updated correctly for: %u\n", index); exit(1); } } for(int i = 0; i < MEM_SEG_LEN; i++) { UArray_T segments = (UArray_T)Seq_get(memorySegments, i); if (segments != NULL) { for(int j = 0; j < UArray_length(segments); j++) { // Each 32-bit word must be initialized to 0 printf("memseg: %u\n", *(UM_Word*)UArray_at(segments, j)); if(*(UM_Word*)UArray_at(segments, j) != 0) { fprintf(stderr, "segment incorrectly initialized\n"); exit(1); } } } } printf("Verified bitch.\n"); }
//UArray void *UArray2_at(T array2, int row, int col) { UArray_T* p = UArray_at(array2 -> array, row); //assert(sizeof(*p)) == UArray_size(uarray2 -> array); UArray_T inner_array = *p; int* q = UArray_at(inner_array, col); return (int*)q; }
extern void nand(void *machine_p, unsigned A, unsigned B, unsigned C) { UM_machine machine = (UM_machine) machine_p; UArray_T registers = machine->registers; UM_word *rB = UArray_at(registers, B); UM_word *rC = UArray_at(registers, C); UM_word nand = ~(*rB & *rC); UM_word *rA = UArray_at(registers, A); *rA = nand; }
extern void add(void *machine_p, unsigned A, unsigned B, unsigned C) { UM_machine machine = (UM_machine) machine_p; UArray_T registers = machine->registers; UM_word *rB = UArray_at(registers, B); UM_word *rC = UArray_at(registers, C); UM_word sum = *rB + *rC; UM_word *rA = UArray_at(registers, A); *rA = sum; }
extern void mult(void *machine_p, unsigned A, unsigned B, unsigned C) { UM_machine machine = (UM_machine) machine_p; UArray_T registers = machine->registers; UM_word *rB = UArray_at(registers, B); UM_word *rC = UArray_at(registers, C); UM_word product = *rB * *rC; UM_word *rA = UArray_at(registers, A); *rA = product; }
extern void divi(void *machine_p, unsigned A, unsigned B, unsigned C) { UM_machine machine = (UM_machine) machine_p; UArray_T registers = machine->registers; UM_word *rB = UArray_at(registers, B); UM_word *rC = UArray_at(registers, C); UM_word quotient = *rB / *rC; UM_word *rA = UArray_at(registers, A); *rA = quotient; }
extern void movc(void *machine_p, unsigned A, unsigned B, unsigned C) { UM_machine machine = (UM_machine) machine_p; UArray_T registers = machine->registers; UM_word *rC = UArray_at(registers, C); /* if $r[C] != 0, $r[A] = $r[B] */ if(*rC != 0){ UM_word *rA = UArray_at(registers, A); UM_word *rB = UArray_at(registers, B); *rA = *rB; } }
void* UArray2b_at(T array2b, int i, int j) { assert(array2b); int blocksize = array2b->blocksize; UArray_T *temp = UArray2_at(array2b->blocks, i/blocksize, j/blocksize); UArray_T block = *temp; return UArray_at(block, blocksize * (i % blocksize) + (j % blocksize)); }
void verifyMapped(Seq_T memorySegments, Seq_T unmappedSegments) { assert(Seq_length(memorySegments) == Seq_length(unmappedSegments)); for(int i = 0; i < Seq_length(memorySegments); i++){ if(Seq_get(memorySegments, i) == Seq_get(unmappedSegments, i)){ fprintf(stderr, "Cannot be both mapped and unmapped: %d\n", i); /* if(Seq_get(unmappedSegments, i) == NULL) { fprintf(stderr, "Both NULL\n"); }*/ exit(1); } if(Seq_get(memorySegments, i) != NULL) { if(Seq_get(unmappedSegments, i) != NULL){ fprintf(stderr, "Failed to unmap index: %d\n", i); exit(1); } UArray_T temp = Seq_get(memorySegments, i); for(UM_Word j = 0; j < (UM_Word)UArray_length(temp); j++) { UM_Word value = *(UM_Word*)UArray_at(temp, j); if(value != 0){ printf("Segmented load at %d with value of %u\n", i, value); } } } } printf("Verified\n"); }
/*-----------------------------------------------------------------------------* | UArray2_at | Purpose: finds the element stored at the specified matrix location of | the given UArray2 | Arguments: a pointer to a 2D array, the matrix location to be accessed | as a pair of ints | Returns: a pointer to the element at the given matrix location | Fail cases: | - the pointer to the 2D array is null | - the matrix location lies outside of the bounds of the 2D array *-----------------------------------------------------------------------------*/ void *UArray2_at(UArray2_T uarray2, int i, int j) { assert(uarray2 != NULL); assert((i >= 0 && i < UArray2_width(uarray2)) && (j >= 0 && j < UArray2_height(uarray2))); int index = get_index(i, j, UArray2_height(uarray2)); return UArray_at(uarray2->uarray, index); }
void registers_to_zero() { for (int i = 0; i < NUM_REGS; i++) { uint32_t *v = (uint32_t *)UArray_at(um->registers, i); *v = 0; } }
extern void loadp(void *machine_p, unsigned B, unsigned C) { UM_machine machine = (UM_machine) machine_p; UArray_T registers = machine->registers; UM_word *rB = UArray_at(registers, B); /* no need to duplicate if *rB = 0 */ if(*rB != 0){ copy_segment_to_m0(machine, *rB); } UM_word *rC = UArray_at(registers, C); machine->program_counter = *rC; }
/* this function takes in the UArray_T of the pixels, and outputs the Y, Pb, Pr representation */ CVC *rgb_pixels_to_CVC(UArray_T block, int denominator) { int num_pixels = UArray_length(block); float avg_Pb = 0.0; float avg_Pr = 0.0; Pnm_rgb cur_pix; Pnm_rgb_float cur_pix_float; CVC *YPbPr = malloc(sizeof(struct CVC)); assert(YPbPr); YPbPr->Y = malloc(sizeof(Lum_vals) * num_pixels); assert(YPbPr->Y); YPbPr->num_vals = num_pixels; for (int i = 0; i < num_pixels; i++) { cur_pix = (Pnm_rgb)UArray_at(block, i); cur_pix_float = normalize_pixel(cur_pix, denominator); YPbPr->Y[i] = get_Y(cur_pix_float); avg_Pb += get_Pb(cur_pix_float); avg_Pr += get_Pr(cur_pix_float); free(cur_pix_float); } YPbPr->avg_Pb = avg_Pb / (float)num_pixels; YPbPr->avg_Pr = avg_Pr / (float)num_pixels; return YPbPr; }
bool put_word(Segment s, uint32_t ID, uint32_t address, uint32_t word) { TRY assert(s); UArray_T inner = Seq_get(s, ID); assert(inner); if (ID >= (unsigned) Seq_length(s)) { /* ID does not exist */ return false; } if (address >= (unsigned) UArray_length(inner)) { /* offset does not exist */ return false; } assert(inner); uint32_t *wordptr = UArray_at(inner, address); *wordptr = word; EXCEPT(Mem_Failed) return false; END_TRY; return true; }
/* this function takes in the Y, Pb, Pr representation and outputs the 4 pixels in a UArray_T */ UArray_T CVC_to_rgb_pixels(CVC *YPbPr) { UArray_T r_array = UArray_new(PIX_PER_BLOCK, sizeof(struct Pnm_rgb)); assert(r_array != NULL); Pnm_rgb cur_pix; Pnm_rgb_float cur_pix_float = malloc(sizeof(struct Pnm_rgb_float)); for (int i = 0; i < PIX_PER_BLOCK; i++) { cur_pix = (Pnm_rgb)UArray_at(r_array, i); assert(cur_pix != NULL); cur_pix_float->red = get_R(YPbPr, i); cur_pix_float->green = get_G(YPbPr, i); cur_pix_float->blue = get_B(YPbPr, i); denormalize_pixel(cur_pix_float, DEFAULT_DENOMINATOR); /* we could have rounded this properly before assigning to integers, but we ran out of time. sorry! */ cur_pix->red = cur_pix_float->red; cur_pix->blue = cur_pix_float->blue; cur_pix->green = cur_pix_float->green; } free(cur_pix_float); return r_array; }
extern void loadv(void *machine_p, UM_word value, unsigned A) { UM_machine machine = (UM_machine) machine_p; UArray_T registers = machine->registers; UM_word *rA = (UM_word *) UArray_at(registers, A); *rA = value; }
/* * Creates a new segment of length given as a parameter * Parameters: sm - Segment manager struct * length - length of segment to create */ unsigned map_Segment(Segment_Manager sm, int length) { Segment segment = (Segment)UArray_new(length, sizeof(uint32_t)); for (int i=0; i<length; i++) { *((uint32_t *)UArray_at(segment, i)) = 0; } unsigned id = insert_Segment(sm, segment); return id; }
extern void segs(void *machine_p, unsigned segmentID_reg, unsigned offset_reg, unsigned C) { UM_machine machine = (UM_machine) machine_p; UM_address_space address_space = machine->address_space; UArray_T registers = machine->registers; Seq_T mapped_segments = address_space->mapped_segments; UM_word segmentID = *((UM_word *) UArray_at(registers, segmentID_reg)); UM_word offset = *((UM_word *) UArray_at(registers, offset_reg)); UM_segment segment = Seq_get(mapped_segments, segmentID); UM_word *word_p = UArray_at(segment->words, offset); UM_word *rC = UArray_at(registers, C); /*$m[$r[A]][$r[B]] = $r[C]*/ *word_p = *rC; }
extern void out(void *machine_p, unsigned C) { UM_machine machine = (UM_machine) machine_p; UArray_T registers = machine->registers; UM_word *rC = UArray_at(registers, C); UM_word output = *rC; putc(output, stdout); }
void UArray2_free(T *uarray2) { int i; for(i = 0; i < (*uarray2) -> height; i++) { UArray_free(UArray_at((*uarray2) -> array, i)); } UArray_free(&(*uarray2) -> array); FREE (*uarray2); return; }
static UArray_T get_new_registers() { UArray_T registers = UArray_new(8, sizeof(UM_word)); /* initialize each register to 0 */ for(int i=0; i<8; i++){ UM_word *rI = UArray_at(registers, i); *rI = 0; } return registers; }
/* * Sets the value of segment[id][offset] to the given value * Parameters: sm - Segment manager struct * id - ID of segment to set * offset - Offset within the segment * value - Value to set * Return value: the old value of the specified segment[id][offset] */ uint32_t seg_Set(Segment_Manager sm, unsigned id, unsigned offset, uint32_t value) { uint32_t old_value; Segment segment = Seq_get(sm->Segment_Table, id); uint32_t *location = UArray_at(segment, offset); old_value = *location; *location = value; return old_value; }
/* returns the word stored at index address in the segment with id ID */ uint32_t get_word(Segment s, uint32_t ID, uint32_t address) { assert(s); if(ID != 0 ){ assert((signed) ID < get_num_segs(s)); } UArray_T inner = Seq_get(s, ID); assert(inner); uint32_t *wordptr = UArray_at(inner, address); return *wordptr; }
extern void in(void *machine_p, unsigned C) { UM_machine machine = (UM_machine) machine_p; UArray_T registers = machine->registers; UM_word store_value = 0; int input = getchar(); if(input < 0){ store_value = ~store_value; } else{ store_value = input; assert(store_value < 256); } UM_word *rC = UArray_at(registers, C); *rC = store_value; }
/*bool append_word(Segment s, uint32_t ID, uint32_t word) { TRY assert(s); assert(ID < (unsigned) Seq_length(s)); UArray_T inner = (UArray_T) Seq_get(s, ID); Seq_addhi(inner, wp); EXCEPT(Mem_Failed) return false; END_TRY; return true; } */ bool resize(Segment s, uint32_t ID, int length) { TRY assert(s); assert(ID < (unsigned) Seq_length(s)); UArray_T inner = Seq_get(s, ID); UArray_resize(inner, length); for (int i = 0; i < (int) length; i++) { uint32_t *wordptr = UArray_at(inner, i); *wordptr = 0; } EXCEPT(Mem_Failed) return false; END_TRY; return true; }
static int execute_cycle(UM_machine machine) { Seq_T mapped_segments = machine->address_space->mapped_segments; UM_segment program_segment = Seq_get(mapped_segments, 0); unsigned num_instructions = machine->num_instructions; /* stop if program counter has run out of bounds */ if(machine->program_counter >= num_instructions) return 0; /* retreive the next instruction */ Um_instruction new_instruction = *((Um_instruction *)UArray_at(program_segment->words, machine->program_counter)); /* increment the program counter */ machine->program_counter++; /* decode and execute the instruction retreived */ return decode_instruction(machine, &new_instruction); }
static void add_program_segment(UM_machine machine, char *file) { struct stat fileStats; FILE *FILE = fopen(file, "r"); /* exit if the file does not exist or if stat fails */ if(stat(file, &fileStats) < 0){ fprintf(stderr, "Stat failed. Invalid file.\n"); exit(EXIT_FAILURE); } int fileSize = fileStats.st_size; /* exit if fileSize indicates the wrong number of bytes */ if(fileSize%4 != 0){ fprintf(stderr, "Program file formatted incorrectly.\n"); exit(EXIT_FAILURE); } int num_instructions = fileSize / BYTES_PER_INSTRUCTION; UM_segment program_segment = get_new_segment_of_size(num_instructions); /* get the instructions from the input file */ for(int i=0; i<num_instructions; i++){ UM_instruction next_instruction = get_next_instruction(FILE); UM_instruction *instruction_i_p = UArray_at(program_segment->words, i); *instruction_i_p = next_instruction; } /* put the program segment in the mapped segments sequence */ Seq_addlo(machine->address_space->mapped_segments, program_segment); machine->address_space->ID_counter++; machine->num_instructions = num_instructions; fclose(FILE); }
/* creates/allocates space for a new segment in the overall Segments */ bool create_segment(Segment s, uint32_t length) { TRY UArray_T inner = UArray_new(length, sizeof(uint32_t)); if (inner == NULL) { return false; } for (int i = 0; i < (int) length; i++) { uint32_t *wordptr = UArray_at(inner, i); *wordptr = 0; } Seq_addhi(s, inner); EXCEPT (Mem_Failed) return false; END_TRY; return true; }