Tabs vs spaces

This commit is contained in:
2026-01-19 14:16:44 +01:00
parent 0b23707041
commit fa42b20136

View File

@@ -288,18 +288,18 @@ static void gen_modrm_impl(int op_reg, int r, Sym *sym, int c, int is_got)
op_reg = REG_VALUE(op_reg) << 3;
if ((r & VT_VALMASK) == VT_CONST) {
/* constant memory reference */
if (!(r & VT_SYM)) {
/* Absolute memory reference */
o(0x04 | op_reg); /* [sib] | destreg */
oad(0x25, c); /* disp32 */
} else {
o(0x05 | op_reg); /* (%rip)+disp32 | destreg */
if (is_got) {
gen_gotpcrel(r, sym, c);
} else {
gen_addrpc32(r, sym, c);
}
}
if (!(r & VT_SYM)) {
/* Absolute memory reference */
o(0x04 | op_reg); /* [sib] | destreg */
oad(0x25, c); /* disp32 */
} else {
o(0x05 | op_reg); /* (%rip)+disp32 | destreg */
if (is_got) {
gen_gotpcrel(r, sym, c);
} else {
gen_addrpc32(r, sym, c);
}
}
} else if ((r & VT_VALMASK) == VT_LOCAL) {
/* currently, we use only ebp as base */
if (c == (char)c) {
@@ -387,36 +387,36 @@ void load(int r, SValue *sv)
fr = get_reg(RC_INT);
load(fr, &v1);
}
if (fc != sv->c.i) {
/* If the addends doesn't fit into a 32bit signed
we must use a 64bit move. We've checked above
that this doesn't have a sym associated. */
v1.type.t = VT_LLONG;
v1.r = VT_CONST;
v1.c.i = sv->c.i;
fr = r;
if (!(reg_classes[fr] & (RC_INT|RC_R11)))
fr = get_reg(RC_INT);
load(fr, &v1);
fc = 0;
}
if (fc != sv->c.i) {
/* If the addends doesn't fit into a 32bit signed
we must use a 64bit move. We've checked above
that this doesn't have a sym associated. */
v1.type.t = VT_LLONG;
v1.r = VT_CONST;
v1.c.i = sv->c.i;
fr = r;
if (!(reg_classes[fr] & (RC_INT|RC_R11)))
fr = get_reg(RC_INT);
load(fr, &v1);
fc = 0;
}
ll = 0;
/* Like GCC we can load from small enough properly sized
structs and unions as well.
XXX maybe move to generic operand handling, but should
occur only with asm, so tccasm.c might also be a better place */
if ((ft & VT_BTYPE) == VT_STRUCT) {
int align;
switch (type_size(&sv->type, &align)) {
case 1: ft = VT_BYTE; break;
case 2: ft = VT_SHORT; break;
case 4: ft = VT_INT; break;
case 8: ft = VT_LLONG; break;
default:
tcc_error("invalid aggregate type for register load");
break;
}
}
/* Like GCC we can load from small enough properly sized
structs and unions as well.
XXX maybe move to generic operand handling, but should
occur only with asm, so tccasm.c might also be a better place */
if ((ft & VT_BTYPE) == VT_STRUCT) {
int align;
switch (type_size(&sv->type, &align)) {
case 1: ft = VT_BYTE; break;
case 2: ft = VT_SHORT; break;
case 4: ft = VT_INT; break;
case 8: ft = VT_LLONG; break;
default:
tcc_error("invalid aggregate type for register load");
break;
}
}
if ((ft & VT_BTYPE) == VT_FLOAT) {
b = 0x6e0f66;
r = REG_VALUE(r); /* movd */
@@ -478,18 +478,18 @@ void load(int r, SValue *sv)
gen_modrm(r, VT_LOCAL, sv->sym, fc);
} else if (v == VT_CMP) {
orex(0,r,0,0);
if ((fc & ~0x100) != TOK_NE)
if ((fc & ~0x100) != TOK_NE)
oad(0xb8 + REG_VALUE(r), 0); /* mov $0, r */
else
else
oad(0xb8 + REG_VALUE(r), 1); /* mov $1, r */
if (fc & 0x100)
{
/* This was a float compare. If the parity bit is
set the result was unordered, meaning false for everything
except TOK_NE, and true for TOK_NE. */
fc &= ~0x100;
o(0x037a + (REX_BASE(r) << 8));
}
if (fc & 0x100)
{
/* This was a float compare. If the parity bit is
set the result was unordered, meaning false for everything
except TOK_NE, and true for TOK_NE. */
fc &= ~0x100;
o(0x037a + (REX_BASE(r) << 8));
}
orex(0,r,0, 0x0f); /* setxx %br */
o(fc);
o(0xc0 + REG_VALUE(r));
@@ -623,7 +623,7 @@ static void gcall_or_jmp(int is_jmp)
{
int r;
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
((vtop->r & VT_SYM) || (vtop->c.i-4) == (int)(vtop->c.i-4))) {
((vtop->r & VT_SYM) || (vtop->c.i-4) == (int)(vtop->c.i-4))) {
/* constant case */
if (vtop->r & VT_SYM) {
/* relocation case */
@@ -875,8 +875,8 @@ void gfunc_call(int nb_args)
struct_size += size;
} else {
if (is_sse_float(vtop->type.t)) {
if (tcc_state->nosse)
tcc_error("SSE disabled");
if (tcc_state->nosse)
tcc_error("SSE disabled");
gv(RC_XMM0); /* only use one float register */
if (arg >= REGN) {
/* movq %xmm0, j*8(%rsp) */
@@ -994,8 +994,8 @@ void gfunc_prolog(CType *func_type)
if (reg_param_index < REGN) {
/* save arguments passed by register */
if ((bt == VT_FLOAT) || (bt == VT_DOUBLE)) {
if (tcc_state->nosse)
tcc_error("SSE disabled");
if (tcc_state->nosse)
tcc_error("SSE disabled");
o(0xd60f66); /* movq */
gen_modrm(reg_param_index, VT_LOCAL, NULL, addr);
} else {
@@ -1252,20 +1252,20 @@ void gfunc_call(int nb_args)
mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, &reg_count);
if (mode == x86_64_mode_sse && nb_sse_args + reg_count <= 8) {
nb_sse_args += reg_count;
onstack[i] = 0;
} else if (mode == x86_64_mode_integer && nb_reg_args + reg_count <= REGN) {
onstack[i] = 0;
} else if (mode == x86_64_mode_integer && nb_reg_args + reg_count <= REGN) {
nb_reg_args += reg_count;
onstack[i] = 0;
} else if (mode == x86_64_mode_none) {
onstack[i] = 0;
} else {
if (align == 16 && (stack_adjust &= 15)) {
onstack[i] = 2;
stack_adjust = 0;
} else
onstack[i] = 1;
stack_adjust += size;
}
onstack[i] = 0;
} else if (mode == x86_64_mode_none) {
onstack[i] = 0;
} else {
if (align == 16 && (stack_adjust &= 15)) {
onstack[i] = 2;
stack_adjust = 0;
} else
onstack[i] = 1;
stack_adjust += size;
}
}
if (nb_sse_args && tcc_state->nosse)
@@ -1283,71 +1283,71 @@ void gfunc_call(int nb_args)
args_size = 0;
stack_adjust &= 15;
for (i = 0; i < nb_args;) {
mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, &reg_count);
if (!onstack[i]) {
++i;
continue;
}
/* Possibly adjust stack to align SSE boundary. We're processing
args from right to left while allocating happens left to right
(stack grows down), so the adjustment needs to happen _after_
an argument that requires it. */
if (stack_adjust) {
o(0x50); /* push %rax; aka sub $8,%rsp */
args_size += 8;
stack_adjust = 0;
mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, &reg_count);
if (!onstack[i]) {
++i;
continue;
}
if (onstack[i] == 2)
stack_adjust = 1;
/* Possibly adjust stack to align SSE boundary. We're processing
args from right to left while allocating happens left to right
(stack grows down), so the adjustment needs to happen _after_
an argument that requires it. */
if (stack_adjust) {
o(0x50); /* push %rax; aka sub $8,%rsp */
args_size += 8;
stack_adjust = 0;
}
if (onstack[i] == 2)
stack_adjust = 1;
vrotb(i+1);
vrotb(i+1);
switch (vtop->type.t & VT_BTYPE) {
case VT_STRUCT:
/* allocate the necessary size on stack */
o(0x48);
oad(0xec81, size); /* sub $xxx, %rsp */
/* generate structure store */
r = get_reg(RC_INT);
orex(1, r, 0, 0x89); /* mov %rsp, r */
o(0xe0 + REG_VALUE(r));
vset(&vtop->type, r | VT_LVAL, 0);
vswap();
vstore();
break;
switch (vtop->type.t & VT_BTYPE) {
case VT_STRUCT:
/* allocate the necessary size on stack */
o(0x48);
oad(0xec81, size); /* sub $xxx, %rsp */
/* generate structure store */
r = get_reg(RC_INT);
orex(1, r, 0, 0x89); /* mov %rsp, r */
o(0xe0 + REG_VALUE(r));
vset(&vtop->type, r | VT_LVAL, 0);
vswap();
vstore();
break;
case VT_LDOUBLE:
case VT_LDOUBLE:
gv(RC_ST0);
oad(0xec8148, size); /* sub $xxx, %rsp */
o(0x7cdb); /* fstpt 0(%rsp) */
g(0x24);
g(0x00);
break;
break;
case VT_FLOAT:
case VT_DOUBLE:
assert(mode == x86_64_mode_sse);
r = gv(RC_FLOAT);
o(0x50); /* push $rax */
/* movq %xmmN, (%rsp) */
o(0xd60f66);
o(0x04 + REG_VALUE(r)*8);
o(0x24);
break;
case VT_FLOAT:
case VT_DOUBLE:
assert(mode == x86_64_mode_sse);
r = gv(RC_FLOAT);
o(0x50); /* push $rax */
/* movq %xmmN, (%rsp) */
o(0xd60f66);
o(0x04 + REG_VALUE(r)*8);
o(0x24);
break;
default:
assert(mode == x86_64_mode_integer);
/* simple type */
/* XXX: implicit cast ? */
r = gv(RC_INT);
orex(0,r,0,0x50 + REG_VALUE(r)); /* push r */
break;
}
args_size += size;
default:
assert(mode == x86_64_mode_integer);
/* simple type */
/* XXX: implicit cast ? */
r = gv(RC_INT);
orex(0,r,0,0x50 + REG_VALUE(r)); /* push r */
break;
}
args_size += size;
vpop();
--nb_args;
onstack++;
vpop();
--nb_args;
onstack++;
}
/* XXX This should be superfluous. */
@@ -1465,14 +1465,14 @@ void gfunc_prolog(CType *func_type)
case x86_64_mode_integer:
if (seen_reg_num + reg_count > REGN)
goto stack_arg;
seen_reg_num += reg_count;
goto stack_arg;
seen_reg_num += reg_count;
break;
case x86_64_mode_sse:
if (seen_sse_num + reg_count > 8)
goto stack_arg;
seen_sse_num += reg_count;
goto stack_arg;
seen_sse_num += reg_count;
break;
}
}
@@ -1491,10 +1491,10 @@ void gfunc_prolog(CType *func_type)
/* save all register passing arguments */
for (i = 0; i < 8; i++) {
loc -= 16;
if (!tcc_state->nosse) {
o(0xd60f66); /* movq */
gen_modrm(7 - i, VT_LOCAL, NULL, loc);
}
if (!tcc_state->nosse) {
o(0xd60f66); /* movq */
gen_modrm(7 - i, VT_LOCAL, NULL, loc);
}
/* movq $0, loc+8(%rbp) */
o(0x85c748);
gen_le32(loc + 8);
@@ -1524,8 +1524,8 @@ void gfunc_prolog(CType *func_type)
mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);
switch (mode) {
case x86_64_mode_sse:
if (tcc_state->nosse)
tcc_error("SSE disabled but floating point arguments used");
if (tcc_state->nosse)
tcc_error("SSE disabled but floating point arguments used");
if (sse_param_index + reg_count <= 8) {
/* save arguments passed by register */
loc -= reg_count * 8;
@@ -1565,7 +1565,7 @@ void gfunc_prolog(CType *func_type)
}
break;
}
default: break; /* nothing to be done for x86_64_mode_none */
default: break; /* nothing to be done for x86_64_mode_none */
}
sym_push(sym->v & ~SYM_FIELD, type,
VT_LOCAL | VT_LVAL, param_addr);
@@ -1577,8 +1577,8 @@ void gfunc_prolog(CType *func_type)
func_bound_offset = lbounds_section->data_offset;
func_bound_ind = ind;
oad(0xb8, 0); /* lbound section pointer */
o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */
oad(0xb8, 0); /* call to function */
o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */
oad(0xb8, 0); /* call to function */
}
#endif
}
@@ -1590,7 +1590,7 @@ void gfunc_epilog(void)
#ifdef CONFIG_TCC_BCHECK
if (tcc_state->do_bounds_check
&& func_bound_offset != lbounds_section->data_offset)
&& func_bound_offset != lbounds_section->data_offset)
{
addr_t saved_ind;
addr_t *bounds_ptr;
@@ -1662,25 +1662,25 @@ ST_FUNC void gtst_addr(int inv, int a)
{
int v = vtop->r & VT_VALMASK;
if (v == VT_CMP) {
inv ^= (vtop--)->c.i;
a -= ind + 2;
if (a == (char)a) {
g(inv - 32);
g(a);
} else {
g(0x0f);
oad(inv - 16, a - 4);
}
inv ^= (vtop--)->c.i;
a -= ind + 2;
if (a == (char)a) {
g(inv - 32);
g(a);
} else {
g(0x0f);
oad(inv - 16, a - 4);
}
} else if ((v & ~1) == VT_JMP) {
if ((v & 1) != inv) {
gjmp_addr(a);
gsym(vtop->c.i);
} else {
gsym(vtop->c.i);
o(0x05eb);
gjmp_addr(a);
}
vtop--;
if ((v & 1) != inv) {
gjmp_addr(a);
gsym(vtop->c.i);
} else {
gsym(vtop->c.i);
o(0x05eb);
gjmp_addr(a);
}
vtop--;
}
}
@@ -1693,24 +1693,24 @@ ST_FUNC int gtst(int inv, int t)
;
} else if (v == VT_CMP) {
/* fast case : can jump directly since flags are set */
if (vtop->c.i & 0x100)
{
/* This was a float compare. If the parity flag is set
the result was unordered. For anything except != this
means false and we don't jump (anding both conditions).
For != this means true (oring both).
Take care about inverting the test. We need to jump
to our target if the result was unordered and test wasn't NE,
otherwise if unordered we don't want to jump. */
vtop->c.i &= ~0x100;
if (vtop->c.i & 0x100)
{
/* This was a float compare. If the parity flag is set
the result was unordered. For anything except != this
means false and we don't jump (anding both conditions).
For != this means true (oring both).
Take care about inverting the test. We need to jump
to our target if the result was unordered and test wasn't NE,
otherwise if unordered we don't want to jump. */
vtop->c.i &= ~0x100;
if (inv == (vtop->c.i == TOK_NE))
o(0x067a); /* jp +6 */
else
{
g(0x0f);
t = gjmp2(0x8a, t); /* jp t */
}
}
o(0x067a); /* jp +6 */
else
{
g(0x0f);
t = gjmp2(0x8a, t); /* jp t */
}
}
g(0x0f);
t = gjmp2((vtop->c.i - 16) ^ inv, t);
} else if (v == VT_JMP || v == VT_JMPI) {