void generate_code(FILE *file, Tac *code, SymbolTable *programTable, SymbolTable *constantTable) { //Get our register descriptors RegDesc registers[REG_MAX]; Tac *current = code; //Clear registers name_registers(registers); clear_registers(registers); //Put our constant strings in the file code_strings(file, constantTable); while (current != NULL) { code_comment(file, "Current %d", current); code_tac(file, registers, current); current = current->next; } }
char *get_destination(FILE *file, RegDesc *registers, Symbol *symbol) { debug("Getting destination for %s in scope %s", symbol->name, current_scope->name); char *name; if (symbol->is_array_element) name = symbol->array->name; else name = symbol->name; Symbol *lookup = symboltable_lookup(current_scope->symbols, name); char *base; if (lookup == NULL) { debug("Variable declared in another scope"); //Load our SL into EDI code_instruction(file, MOVE, CURRENT_STATIC_LINK, EDI); int hops = 0; SymbolTable *current = current_scope->symbols; while (symboltable_lookup(current, name) == NULL) { hops++; current = current->parent; } int i; for (i = 0; i < hops - 1; i++) { code_instruction(file, MOVE, make_relative_address(0, EDI), EDI); } code_instruction(file, ADD, make_integer(4), EDI); base = EDI; } else { base = EBP; } if (symbol->is_array_element == FALSE) { code_comment(file, "Variable %s", symbol->name); return make_memory_offset(symbol, base); } else { //We have a bit more work //If the index is a constant, we can give a constant address Symbol *array = symbol->array; Symbol *index = symbol->index; if (index->type->code == TYPE_NATURAL) { //Calculate constant offset int offset = array->type->c + index->value.integer * 4; debug("Constant offset"); code_comment(file, "Array Constant Index for %s", symbol->name); return make_relative_address(offset, base); } else { //AT&T has a syntax for arrays: //0(%ebp, %esi, 4) -> 0 + %ebp + %esi * 4 //I want to avoidl multiplying the index by negative one...lets think about this //Well I flipped the array in memory so the last index is first, we now solved our problem code_comment(file, "Array Variable Index for %s", symbol->name); //Step 1: load index code_instruction(file, MOVE, get_location(file, registers, index), ESI); //code_instruction(file, MOVE, get_destination(file, registers, index), ESI); //Step 2: print char *dest = make_array_offset(array->type->c, base, ESI); code_comment(file, "Index: %s", dest); return dest; } } }
void JB2Dict::JB2Codec::code_record( int &rectype, const GP<JB2Dict> &gjim, JB2Shape *xjshp) { GP<GBitmap> cbm; GP<GBitmap> bm; int shapeno = -1; // Code record type code_record_type(rectype); // Pre-coding actions switch(rectype) { case NEW_MARK_LIBRARY_ONLY: case MATCHED_REFINE_LIBRARY_ONLY: { if(!xjshp) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Shape &jshp=*xjshp; if (!encoding) { jshp.bits = GBitmap::create(); jshp.parent = -1; } bm = jshp.bits; break; } } // Coding actions switch (rectype) { case START_OF_DATA: { if(!gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Dict &jim=*gjim; code_image_size (jim); code_eventual_lossless_refinement (); if (! encoding) init_library(jim); break; } case NEW_MARK_LIBRARY_ONLY: { code_absolute_mark_size (*bm, 4); code_bitmap_directly (*bm); break; } case MATCHED_REFINE_LIBRARY_ONLY: { if(!xjshp||!gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Dict &jim=*gjim; JB2Shape &jshp=*xjshp; int match = code_match_index (jshp.parent, jim); cbm = jim.get_shape(jshp.parent).bits; LibRect &l = libinfo[match]; code_relative_mark_size (*bm, l.right-l.left+1, l.top-l.bottom+1, 4); code_bitmap_by_cross_coding (*bm, cbm, jshp.parent); break; } case PRESERVED_COMMENT: { if(!gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Dict &jim=*gjim; code_comment(jim.comment); break; } case REQUIRED_DICT_OR_RESET: { if (! gotstartrecordp) { // Indicates need for a shape dictionary if(!gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } code_inherited_shape_count(*gjim); }else // Reset all numerical contexts to zero reset_numcoder(); break; } case END_OF_DATA: { break; } default: { G_THROW( ERR_MSG("JB2Image.bad_type") ); } } // Post-coding action if (!encoding) { // add shape to dictionary switch(rectype) { case NEW_MARK_LIBRARY_ONLY: case MATCHED_REFINE_LIBRARY_ONLY: { if(!xjshp||!gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Shape &jshp=*xjshp; shapeno = gjim->add_shape(jshp); add_library(shapeno, jshp); break; } } // make sure everything is compacted // decompaction will occur automatically when needed if (bm) bm->compress(); } }
void JB2Dict::JB2Codec::code_record( int &rectype, const GP<JB2Image> &gjim, JB2Shape *xjshp, JB2Blit *jblt) { GP<GBitmap> bm; GP<GBitmap> cbm; int shapeno = -1; int match; // Code record type code_record_type(rectype); // Pre-coding actions switch(rectype) { case NEW_MARK: case NEW_MARK_LIBRARY_ONLY: case NEW_MARK_IMAGE_ONLY: case MATCHED_REFINE: case MATCHED_REFINE_LIBRARY_ONLY: case MATCHED_REFINE_IMAGE_ONLY: case NON_MARK_DATA: { if(!xjshp) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Shape &jshp=*xjshp; if (!encoding) { jshp.bits = GBitmap::create(); jshp.parent = -1; if (rectype == NON_MARK_DATA) jshp.parent = -2; } bm = jshp.bits; break; } } // Coding actions switch (rectype) { case START_OF_DATA: { if(!gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Image &jim=*gjim; code_image_size (jim); code_eventual_lossless_refinement (); if (! encoding) init_library(jim); break; } case NEW_MARK: { code_absolute_mark_size (*bm, 4); code_bitmap_directly (*bm); code_relative_location (jblt, bm->rows(), bm->columns() ); break; } case NEW_MARK_LIBRARY_ONLY: { code_absolute_mark_size (*bm, 4); code_bitmap_directly (*bm); break; } case NEW_MARK_IMAGE_ONLY: { code_absolute_mark_size (*bm, 3); code_bitmap_directly (*bm); code_relative_location (jblt, bm->rows(), bm->columns() ); break; } case MATCHED_REFINE: { if(!xjshp || !gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Shape &jshp=*xjshp; JB2Image &jim=*gjim; match = code_match_index (jshp.parent, jim); cbm = jim.get_shape(jshp.parent).bits; LibRect &l = libinfo[match]; code_relative_mark_size (*bm, l.right-l.left+1, l.top-l.bottom+1, 4); code_bitmap_by_cross_coding (*bm, cbm, match); code_relative_location (jblt, bm->rows(), bm->columns() ); break; } case MATCHED_REFINE_LIBRARY_ONLY: { if(!xjshp||!gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Image &jim=*gjim; JB2Shape &jshp=*xjshp; match = code_match_index (jshp.parent, jim); cbm = jim.get_shape(jshp.parent).bits; LibRect &l = libinfo[match]; code_relative_mark_size (*bm, l.right-l.left+1, l.top-l.bottom+1, 4); break; } case MATCHED_REFINE_IMAGE_ONLY: { if(!xjshp||!gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Image &jim=*gjim; JB2Shape &jshp=*xjshp; match = code_match_index (jshp.parent, jim); cbm = jim.get_shape(jshp.parent).bits; LibRect &l = libinfo[match]; code_relative_mark_size (*bm, l.right-l.left+1, l.top-l.bottom+1, 4); code_bitmap_by_cross_coding (*bm, cbm, match); code_relative_location (jblt, bm->rows(), bm->columns() ); break; } case MATCHED_COPY: { int temp; if (encoding) temp = jblt->shapeno; if(!gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Image &jim=*gjim; match = code_match_index (temp, jim); if (!encoding) jblt->shapeno = temp; bm = jim.get_shape(jblt->shapeno).bits; LibRect &l = libinfo[match]; jblt->left += l.left; jblt->bottom += l.bottom; if (jim.reproduce_old_bug) code_relative_location (jblt, bm->rows(), bm->columns() ); else code_relative_location (jblt, l.top-l.bottom+1, l.right-l.left+1 ); jblt->left -= l.left; jblt->bottom -= l.bottom; break; } case NON_MARK_DATA: { code_absolute_mark_size (*bm, 3); code_bitmap_directly (*bm); code_absolute_location (jblt, bm->rows(), bm->columns() ); break; } case PRESERVED_COMMENT: { if(!gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Image &jim=*gjim; code_comment(jim.comment); break; } case REQUIRED_DICT_OR_RESET: { if(!gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Image &jim=*gjim; if (! gotstartrecordp) // Indicates need for a shape dictionary code_inherited_shape_count(jim); else // Reset all numerical contexts to zero reset_numcoder(); break; } case END_OF_DATA: { break; } default: { G_THROW( ERR_MSG("JB2Image.unknown_type") ); } } // Post-coding action if (!encoding) { // add shape to image switch(rectype) { case NEW_MARK: case NEW_MARK_LIBRARY_ONLY: case NEW_MARK_IMAGE_ONLY: case MATCHED_REFINE: case MATCHED_REFINE_LIBRARY_ONLY: case MATCHED_REFINE_IMAGE_ONLY: case NON_MARK_DATA: { if(!xjshp||!gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } JB2Shape &jshp=*xjshp; shapeno = gjim->add_shape(jshp); shape2lib.touch(shapeno); shape2lib[shapeno] = -1; break; } } // add shape to library switch(rectype) { case NEW_MARK: case NEW_MARK_LIBRARY_ONLY: case MATCHED_REFINE: case MATCHED_REFINE_LIBRARY_ONLY: if(!xjshp) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } add_library(shapeno, *xjshp); break; } // make sure everything is compacted // decompaction will occur automatically on cross-coding bitmaps if (bm) bm->compress(); // add blit to image switch (rectype) { case NEW_MARK: case NEW_MARK_IMAGE_ONLY: case MATCHED_REFINE: case MATCHED_REFINE_IMAGE_ONLY: case NON_MARK_DATA: jblt->shapeno = shapeno; case MATCHED_COPY: if(!gjim) { G_THROW( ERR_MSG("JB2Image.bad_number") ); } gjim->add_blit(* jblt); break; } } }