X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeemitter_binary.c;h=596659e04f23ed8fa9ffba0edc95e6d3a23ddfd7;hb=78bac126e7f9ca55761ab892ebfa9c19a4a65fcf;hp=57650784a7d899139212053b9167d4b349916237;hpb=a4f4c0eec98741b870064f189492455814ebe53e;p=libfirm diff --git a/ir/be/beemitter_binary.c b/ir/be/beemitter_binary.c index 57650784a..596659e04 100644 --- a/ir/be/beemitter_binary.c +++ b/ir/be/beemitter_binary.c @@ -32,6 +32,7 @@ #include "beemitter_binary.h" #include "obst.h" #include "pdeq.h" +#include "error.h" static code_fragment_t *first_fragment; static code_fragment_t *last_fragment; @@ -43,8 +44,8 @@ struct obstack code_fragment_obst; be_emit(8/16/32/entity) call!) */ code_fragment_t *be_get_current_fragment(void) { + code_fragment_t *fragment = (code_fragment_t*)obstack_base(&code_fragment_obst); assert(obstack_object_size(&code_fragment_obst) >= sizeof(code_fragment_t)); - code_fragment_t *fragment = obstack_base(&code_fragment_obst); assert(fragment->magic == CODE_FRAGMENT_MAGIC); return fragment; @@ -60,7 +61,7 @@ static void alloc_fragment(void) assert(obstack_object_size(&code_fragment_obst) == 0); obstack_blank(&code_fragment_obst, sizeof(*fragment)); - fragment = obstack_base(&code_fragment_obst); + fragment = (code_fragment_t*)obstack_base(&code_fragment_obst); memset(fragment, 0, sizeof(*fragment)); #ifndef NDEBUG fragment->magic = CODE_FRAGMENT_MAGIC; @@ -121,7 +122,8 @@ static unsigned align(unsigned offset, unsigned alignment) return offset; } -static bool determine_jumpsize_pass(const binary_emiter_interface_t *interface) +static bool determine_jumpsize_iteration( + const binary_emiter_interface_t *interface) { unsigned offset = 0; unsigned max_offset = 0; @@ -137,7 +139,7 @@ static bool determine_jumpsize_pass(const binary_emiter_interface_t *interface) max_offset = align(max_offset, alignment); if (offset != fragment->offset) { - changed = true; + changed = true; fragment->offset = offset; } fragment->max_offset = max_offset; @@ -161,15 +163,30 @@ static void determine_offsets(const binary_emiter_interface_t *interface) first_fragment->offset = 0; first_fragment->max_offset = 0; - /* pass1: encode minimum/maximum offsets into fragments */ + /* The algorithm calculates a lower and upper bound for the offset of each + * fragment. With this information we can calculate a lower and upper bound + * for the size of each jump instruction. + * A single iteration updates the offset bounds for all fragments and jump + * sizes for each fragment. We iterate until we had an iteration where + * none of the minimum offsets changed. */ do { - changed = determine_jumpsize_pass(interface); + changed = determine_jumpsize_iteration(interface); /* TODO: we should have an abort mode for the case when the offsets don't converge fast enough. We could simply use a pessimistic solution after a few iterations... */ } while (changed); } +void be_emit_entity(ir_entity *entity, bool entity_sign, int offset, + bool is_relative) +{ + (void) entity; + (void) entity_sign; + (void) offset; + (void) is_relative; + panic("not implemented yet"); +} + void be_emit_code(FILE *output, const binary_emiter_interface_t *interface) { unsigned offset; @@ -186,14 +203,15 @@ void be_emit_code(FILE *output, const binary_emiter_interface_t *interface) for (fragment = first_fragment; fragment != NULL; fragment = fragment->next) { unsigned char *jmpbuffer; + unsigned nops; /* assure alignment by emitting nops */ assert(fragment->offset >= offset); - unsigned nops = fragment->offset - offset; + nops = fragment->offset - offset; if (nops > 0) { - unsigned char *nopbuffer = obstack_alloc(&code_fragment_obst, nops); - interface->create_nops(nopbuffer, nops); - emit(output, nopbuffer, nops); + unsigned char *nopbuffer = (unsigned char*)obstack_alloc(&code_fragment_obst, nops); + interface->create_nops(nopbuffer, nops); + emit(output, nopbuffer, nops); offset = fragment->offset; obstack_free(&code_fragment_obst, nopbuffer); } @@ -203,7 +221,7 @@ void be_emit_code(FILE *output, const binary_emiter_interface_t *interface) offset += fragment->len; /* emit the jump */ - jmpbuffer = obstack_alloc(&code_fragment_obst, fragment->jumpsize_min); + jmpbuffer = (unsigned char*)obstack_alloc(&code_fragment_obst, fragment->jumpsize_min); interface->emit_jump(fragment, jmpbuffer); emit(output, jmpbuffer, fragment->jumpsize_min); offset += fragment->jumpsize_min;