History

Fix sub-int returns on x86-64 and i386

the ABIs (and other compilers) extend sub-int return values in the caller. TCC extends them in the callee. For compatibility with those other compilers we have extend them in the caller as well. That introduces a useless double extension in pure TCC-compiled code, but fixing that generally requires that the code generator of TCC would understand sub-int types. For the time being bite the bullet.

Michael Matz committed 7 years ago

Commit 749d19d1 parent 5f737fb2 files · +18 −2Browse files

Unified · Split

2 files
  1. i386-gen.c +1 −0
  2. x86_64-gen.c +17 −2
i386-gen.c+1−0
@@ -369,6 +369,7 @@ static void gcall_or_jmp(int is_jmp) · 368 unmodified lines
369369 rt = vtop->type.ref->type.t;
370370 switch (rt & VT_BTYPE) {
371371 case VT_BYTE:
372+ case VT_BOOL:
372373 if (rt & VT_UNSIGNED) {
373374 o(0xc0b60f); /* movzx %al, %eax */
374375 }
x86_64-gen.c+17−2
@@ -920,7 +920,7 @@ void gfunc_call(int nb_args) · 919 unmodified lines
920920
921921 /* other compilers don't clear the upper bits when returning char/short */
922922 bt = vtop->type.ref->type.t & (VT_BTYPE | VT_UNSIGNED);
923− if (bt == (VT_BYTE | VT_UNSIGNED))
923+ if (bt == (VT_BYTE | VT_UNSIGNED) || (bt & VT_TYPE) == VT_BOOL)
924924 o(0xc0b60f); /* movzbl %al, %eax */
925925 else if (bt == VT_BYTE)
926926 o(0xc0be0f); /* movsbl %al, %eax */
@@ -1230,7 +1230,7 @@ void gfunc_call(int nb_args) · 303 unmodified lines
12301230 {
12311231 X86_64_Mode mode;
12321232 CType type;
1233− int size, align, r, args_size, stack_adjust, i, reg_count;
1233+ int size, align, r, args_size, stack_adjust, i, reg_count, bt;
12341234 int nb_reg_args = 0;
12351235 int nb_sse_args = 0;
12361236 int sse_reg, gen_reg;
@@ -1413,6 +1413,21 @@ void gfunc_call(int nb_args) · 176 unmodified lines
14131413 gcall_or_jmp(0);
14141414 if (args_size)
14151415 gadd_sp(args_size);
1416+ /* other compilers don't clear the upper bits when returning char/short,
1417+ TCC does so for convenience. When we'd stay purely within TCC compiled
1418+ code we wouldn't need this, but for compatibility we have to extend.
1419+ Ideally TCC wouldn't extend at return statements to not do double
1420+ extensions, or would understand sub-int types during expression
1421+ evaluation. */
1422+ bt = vtop->type.ref->type.t & (VT_BTYPE | VT_UNSIGNED);
1423+ if (bt == (VT_BYTE | VT_UNSIGNED) || (bt & VT_TYPE) == VT_BOOL)
1424+ o(0xc0b60f); /* movzbl %al, %eax */
1425+ else if (bt == VT_BYTE)
1426+ o(0xc0be0f); /* movsbl %al, %eax */
1427+ else if (bt == VT_SHORT)
1428+ o(0x98); /* cwtl */
1429+ else if (bt == (VT_SHORT | VT_UNSIGNED))
1430+ o(0xc0b70f); /* movzwl %al, %eax */
14161431 vtop--;
14171432 }
14181433

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t