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
369 rt = vtop->type.ref->type.t;369 rt = vtop->type.ref->type.t;
370 switch (rt & VT_BTYPE) {370 switch (rt & VT_BTYPE) {
371 case VT_BYTE:371 case VT_BYTE:
372 case VT_BOOL:
372 if (rt & VT_UNSIGNED) {373 if (rt & VT_UNSIGNED) {
373 o(0xc0b60f); /* movzx %al, %eax */374 o(0xc0b60f); /* movzx %al, %eax */
374 }375 }
x86_64-gen.c+17−2
@@ -920,7 +920,7 @@ void gfunc_call(int nb_args) · 919 unmodified lines
920 920
921 /* other compilers don't clear the upper bits when returning char/short */921 /* other compilers don't clear the upper bits when returning char/short */
922 bt = vtop->type.ref->type.t & (VT_BTYPE | VT_UNSIGNED);922 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)
924 o(0xc0b60f); /* movzbl %al, %eax */924 o(0xc0b60f); /* movzbl %al, %eax */
925 else if (bt == VT_BYTE)925 else if (bt == VT_BYTE)
926 o(0xc0be0f); /* movsbl %al, %eax */926 o(0xc0be0f); /* movsbl %al, %eax */
@@ -1230,7 +1230,7 @@ void gfunc_call(int nb_args) · 303 unmodified lines
1230{1230{
1231 X86_64_Mode mode;1231 X86_64_Mode mode;
1232 CType type;1232 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;
1234 int nb_reg_args = 0;1234 int nb_reg_args = 0;
1235 int nb_sse_args = 0;1235 int nb_sse_args = 0;
1236 int sse_reg, gen_reg;1236 int sse_reg, gen_reg;
@@ -1413,6 +1413,21 @@ void gfunc_call(int nb_args) · 176 unmodified lines
1413 gcall_or_jmp(0);1413 gcall_or_jmp(0);
1414 if (args_size)1414 if (args_size)
1415 gadd_sp(args_size);1415 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 */
1416 vtop--;1431 vtop--;
1417}1432}
1418 1433

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