AL/AX should be extended to EAX when calling functions. However, the previous code did this only for direct calls, indirect calls were ignored. New code also avoid redundant code when generating JMP instruction. (i.e. expanding code should be generated with CALL instruction only)
Unified · Split
| @@ -346,7 +346,6 @@ static void gcall_or_jmp(int is_jmp) · 345 unmodified lines | ||
| 346 | 346 | { |
| 347 | 347 | int r; |
| 348 | 348 | if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { |
| 349 | − int rt; | |
| 350 | 349 | /* constant case */ |
| 351 | 350 | if (vtop->r & VT_SYM) { |
| 352 | 351 | /* relocation case */ |
| @@ -358,6 +357,14 @@ static void gcall_or_jmp(int is_jmp) · 5 unmodified lines | ||
| 358 | 357 | ind + 1, R_386_PC32, 0); |
| 359 | 358 | } |
| 360 | 359 | oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */ |
| 360 | + } else { | |
| 361 | + /* otherwise, indirect call */ | |
| 362 | + r = gv(RC_INT); | |
| 363 | + o(0xff); /* call/jmp *r */ | |
| 364 | + o(0xd0 + r + (is_jmp << 4)); | |
| 365 | + } | |
| 366 | + if (!is_jmp) { | |
| 367 | + int rt; | |
| 361 | 368 | /* extend the return value to the whole register if necessary |
| 362 | 369 | visual studio and gcc do not always set the whole eax register |
| 363 | 370 | when assigning the return value of a function */ |
| @@ -382,11 +389,6 @@ static void gcall_or_jmp(int is_jmp) · 18 unmodified lines | ||
| 382 | 389 | default: |
| 383 | 390 | break; |
| 384 | 391 | } |
| 385 | − } else { | |
| 386 | − /* otherwise, indirect call */ | |
| 387 | − r = gv(RC_INT); | |
| 388 | − o(0xff); /* call/jmp *r */ | |
| 389 | − o(0xd0 + r + (is_jmp << 4)); | |
| 390 | 392 | } |
| 391 | 393 | } |
| 392 | 394 | |