X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeemitter_binary.c;h=f80246f8fe0432a045ac6e21339f30bec0516b0c;hb=e0e9e9ace61d3ec46e4d09c7ab2c6947b17b2778;hp=57650784a7d899139212053b9167d4b349916237;hpb=a4f4c0eec98741b870064f189492455814ebe53e;p=libfirm diff --git a/ir/be/beemitter_binary.c b/ir/be/beemitter_binary.c index 57650784a..f80246f8f 100644 --- a/ir/be/beemitter_binary.c +++ b/ir/be/beemitter_binary.c @@ -43,8 +43,8 @@ struct obstack code_fragment_obst; be_emit(8/16/32/entity) call!) */ code_fragment_t *be_get_current_fragment(void) { - assert(obstack_object_size(&code_fragment_obst) >= sizeof(code_fragment_t)); code_fragment_t *fragment = obstack_base(&code_fragment_obst); + assert(obstack_object_size(&code_fragment_obst) >= sizeof(code_fragment_t)); assert(fragment->magic == CODE_FRAGMENT_MAGIC); return fragment; @@ -121,7 +121,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 +138,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,9 +162,14 @@ 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... */ @@ -186,10 +192,11 @@ 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);